Problem
The bridge daemon is long-lived by design (it survives Unity domain reloads and editor restarts). A side effect: it also survives unityctl upgrades. After updating the CLI and Unity package, a previously started bridge keeps running the old binary indefinitely:
bridge start short-circuits to Bridge already running for project: ... without comparing the running bridge's version to the CLI's (BridgeClient.StartBridgeAsync).
- The only signal is the
WARNING: Version mismatch! ... Run 'unityctl update' to sync block at the end of unityctl status output.
In practice that warning is ineffective, especially for agent callers: it's a trailing note on a command that otherwise succeeded, mid-task, and nothing ever fails because of the mismatch itself. The result is that bridge-side fixes (e.g. the 0.10.x settle-after-compile and play.exit post-condition work, which live entirely in UnityCtl.Bridge) silently don't apply, and the user experiences already-fixed bugs — timeouts, chaining races — with no error pointing at the real cause.
Suggested fix
The bridge is a stateless daemon and the Unity plugin auto-reconnects, so restarting it is cheap and safe at any point where Unity isn't mid-command:
- Auto-restart on mismatch at connect time: when the CLI connects to a bridge whose version differs from its own, stop it and start the current binary (one-line notice:
Bridge was vX.Y.Z, restarted with vA.B.C). A config flag could opt out for the rare case of intentionally mixed versions.
- At minimum in
bridge start: "already running" should verify the running version and restart on mismatch instead of no-op'ing — that's the command users (and agents) reach for when things act up, and today it silently keeps the stale daemon.
- Make timeout errors self-diagnosing: when an RPC times out and a version mismatch is known, append it to the error, e.g.
note: bridge is 0.9.0 but CLI is 0.10.1 — this may be fixed in newer versions; run 'unityctl update'. Errors are where callers actually look; status warnings are not.
(1) prevents the state from existing; (2) gives a reliable manual escape; (3) catches whatever slips through.
Problem
The bridge daemon is long-lived by design (it survives Unity domain reloads and editor restarts). A side effect: it also survives unityctl upgrades. After updating the CLI and Unity package, a previously started bridge keeps running the old binary indefinitely:
bridge startshort-circuits toBridge already running for project: ...without comparing the running bridge's version to the CLI's (BridgeClient.StartBridgeAsync).WARNING: Version mismatch! ... Run 'unityctl update' to syncblock at the end ofunityctl statusoutput.In practice that warning is ineffective, especially for agent callers: it's a trailing note on a command that otherwise succeeded, mid-task, and nothing ever fails because of the mismatch itself. The result is that bridge-side fixes (e.g. the 0.10.x settle-after-compile and play.exit post-condition work, which live entirely in
UnityCtl.Bridge) silently don't apply, and the user experiences already-fixed bugs — timeouts, chaining races — with no error pointing at the real cause.Suggested fix
The bridge is a stateless daemon and the Unity plugin auto-reconnects, so restarting it is cheap and safe at any point where Unity isn't mid-command:
Bridge was vX.Y.Z, restarted with vA.B.C). A config flag could opt out for the rare case of intentionally mixed versions.bridge start: "already running" should verify the running version and restart on mismatch instead of no-op'ing — that's the command users (and agents) reach for when things act up, and today it silently keeps the stale daemon.note: bridge is 0.9.0 but CLI is 0.10.1 — this may be fixed in newer versions; run 'unityctl update'. Errors are where callers actually look;statuswarnings are not.(1) prevents the state from existing; (2) gives a reliable manual escape; (3) catches whatever slips through.