Switch to Stable does nothing when a remote predates database checks#27461

opened2d agobyTtatop

What happened

A remote machine ("agentbox", connected over SSH) ran Nightly. I wanted to move it to Stable. In Settings → About → Update track I picked Stable and clicked Switch to Stable in the dialog. Nothing happened. No update, no error toast, no request to the remote.

Diagnosis

The dialog skips the remote, but the confirm button stays enabled. Clicking it runs a switch with zero targets, so it does nothing without a message.

  • collectChannelSwitchTargets (apps/web/src/components/sidebar/updateEverything.logic.ts) calls channelSwitchBlockReason. It returns its server predates database checks; update it on Nightly first when the remote's serverConfig.environment.databaseMigration is undefined.
  • The remote ran 0.1.4-nightly.20261028.3824. That build does not report databaseMigration (the string is not in its binary), so the remote is always skipped.
  • The client (desktop 0.1.5) is already on Stable, so switchesLocal is false and localBlocked is ignored. disabledReason is null, so Switch to Stable stays enabled.
  • run() calls everything.run({}) with servers = []. Nothing is sent. The remote's trace has no self-update spans.

The advice in the skip reason is also a trap here. The newest Nightly (0.1.6-nightly.20261030.3917) ships database migration 73, and Stable 0.1.5 knows only up to 72. If the user follows "update it on Nightly first", the switch is then blocked by the next check (its database has changes 0.1.5 does not support yet). The remote's database was at 72, so a direct move to 0.1.5 was safe. The UI had no way to do it.

Suggested direction (not a patch):

  • Disable the confirm button, or show a clear note, when no machine will move and the local app does not switch.
  • When a remote predates database checks, offer the manual command (t3 update --channel stable <version>) instead of "update it on Nightly first", or tell the user to check that the target release covers the database.

Steps to reproduce

  1. Run desktop app 0.1.5 (Stable) on macOS.
  2. Connect a remote over SSH whose boot service runs a Nightly from before databaseMigration was reported (for example 0.1.4-nightly.20261028.3824).
  3. Open Settings → About → Update track and choose Stable.
  4. In the "Switch to Stable?" dialog, click Switch to Stable.
  5. Nothing happens. The remote stays on Nightly.

Version

Client: desktop 0.1.5 (Stable). Remote server: 0.1.4-nightly.20261028.3824 (boot service, linux arm64).

Environment

Client: macOS (Darwin 25.6.0, arm64), desktop 0.1.5. Remote: Linux arm64, systemd user service t3code.service, connected over SSH tunnel.

Evidence

shell
1# Remote descriptor before the fix
2GET /.well-known/t3/environment -> "serverVersion":"0.1.4-nightly.20261028.3824", "serverSelfUpdate":"boot-service"
3
4# Remote nightly binary: feature strings
5serverSelfUpdate: 13 matches
6databaseMigration: 0 matches
7
8# Remote database (read-only)
9effect_sql_migrations max migration_id = 72 (WaitingLinkRequestIndex)
10
11# npm manifests
12t3@latest 0.1.5 t3code.databaseMigration = 72
13t3@nightly 0.1.6-nightly.20261030.3917 t3code.databaseMigration = 73
14
15# Remote server.trace.ndjson around the click: no self-update / updateServer spans

Related issues

#2340 (closed) was also "switching to Stable does nothing", but on the old desktop-only channel logic from 0.0.22. This is the new fleet switch from #26288 and a different cause.

Fix applied or workaround

Ran this on the remote over SSH:

shell
1~/.t3/runtime/versions/0.1.4-nightly.20261028.3824/t3 update --channel stable 0.1.5 --yes

The service restarted on 0.1.5, and /.well-known/t3/environment now reports 0.1.5.

Filed by

Claude Code (claude-opus-5-5) via t3 triage