Before submitting
Area
apps/web
Steps to reproduce
- Install the server on a headless Linux host with
npm i -g t3, and start it with t3 start (no desktop app, no background service, so serverSelfUpdate resolves to null).
- Connect to it from a newer client.
- On the "Server update available" banner, select Copy update command.
Expected behavior
A command that actually leaves the server on the new version after its next restart, matched to how that server was installed:
- global npm install:
npm i -g t3@<version>
- background service:
npx t3@<version> service update (already documented in docs/user/updating.md, but never emitted by the UI)
- foreground
npx relaunch: npx t3@<version> (the current behavior, correct only for this case)
Actual behavior
The toast reads: "Run npx t3@0.0.39-nightly.20260903.1265 on to update it."
npx runs a throwaway copy out of the npx cache and never touches the installed CLI. On a global install the binary stays on the old version, so the next t3 start, systemd unit, tmux relaunch or shell alias comes straight back on it and the banner reappears. Following the copied command exactly does not update the server.
The command is built unconditionally:
// apps/web/src/versionSkew.ts:118
/** The command to hand users whose server cannot update itself. */
export function manualServerUpdateCommand(targetVersion: string): string {
return `npx t3@${targetVersion}`;
}
and ServerUpdateAction.tsx:114 wraps it in Run \${command}` on ${serverLabel} to update it.`
This path is reached whenever resolveServerSelfUpdateCapability returns null (apps/server/src/cloud/selfUpdate.ts:34-40: neither desktop-managed nor launcher-managed), which covers every plain global npm install on a headless host, not just the foreground npx case the wording assumes.
Two possible fixes, in order of preference:
- Have the server report how it was launched (npx cache path vs global npm prefix vs service launcher) and pick the command from that.
- Failing that, change "to update it" to "to relaunch it on this version" and list the install specific alternatives, so the copied string is not presented as an update when it is not one.
Related, same class of problem on the provider side rather than the server side: #5629 (Codex "Update now" runs npm install -g against installs it never verified are npm managed) and #7730 (Homebrew installed CLIs flagged outdated against npm latest). The banner itself came from #5299.
Impact
Minor bug or occasional failure
Version or commit
client 0.0.39-nightly.20260903.1265, server 0.0.34-nightly.20260813.1087
Environment
Linux x64, Node 22, headless server started from a global npm install (npm i -g t3), no desktop app, no background service.
Before submitting
Area
apps/web
Steps to reproduce
npm i -g t3, and start it witht3 start(no desktop app, no background service, soserverSelfUpdateresolves tonull).Expected behavior
A command that actually leaves the server on the new version after its next restart, matched to how that server was installed:
npm i -g t3@<version>npx t3@<version> service update(already documented indocs/user/updating.md, but never emitted by the UI)npxrelaunch:npx t3@<version>(the current behavior, correct only for this case)Actual behavior
The toast reads: "Run
npx t3@0.0.39-nightly.20260903.1265on to update it."npxruns a throwaway copy out of the npx cache and never touches the installed CLI. On a global install the binary stays on the old version, so the nextt3 start, systemd unit, tmux relaunch or shell alias comes straight back on it and the banner reappears. Following the copied command exactly does not update the server.The command is built unconditionally:
and
ServerUpdateAction.tsx:114wraps it inRun \${command}` on ${serverLabel} to update it.`This path is reached whenever
resolveServerSelfUpdateCapabilityreturnsnull(apps/server/src/cloud/selfUpdate.ts:34-40: neither desktop-managed nor launcher-managed), which covers every plain global npm install on a headless host, not just the foregroundnpxcase the wording assumes.Two possible fixes, in order of preference:
Related, same class of problem on the provider side rather than the server side: #5629 (Codex "Update now" runs
npm install -gagainst installs it never verified are npm managed) and #7730 (Homebrew installed CLIs flagged outdated against npm latest). The banner itself came from #5299.Impact
Minor bug or occasional failure
Version or commit
client
0.0.39-nightly.20260903.1265, server0.0.34-nightly.20260813.1087Environment
Linux x64, Node 22, headless server started from a global npm install (
npm i -g t3), no desktop app, no background service.