Skip to content

Copy update command always emits npx t3@<version>, which never updates a globally installed server #9370

Description

@VXNCXNX

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/web

Steps to reproduce

  1. 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).
  2. Connect to it from a newer client.
  3. 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:

  1. Have the server report how it was launched (npx cache path vs global npm prefix vs service launcher) and pick the command from that.
  2. 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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions