This still needs to stay open. At main 96bae546, the resolver still selects vp i -g @opencode/cli from the Vite+ shim path without checking system_first delegation; stable v0.1.1 has the same branch. #22745 is unmerged and explicitly reports that its runtime proof still fails because OpenCode's own updater can choose Vite+ again. #13010 and #22839 address stale server versions, not updating the wrong install. This was a source/history check, not a fresh live-update reproduction.
OpenCode update targets a Vite+ shim that delegates to another install (shimMode system_first), then reports "still outdated"#22741
What happened
Clicking the OpenCode "Update" button (bottom bar) on a remote environment ("Mac Studio") ended with:
Update failed — Mac Studio · OpenCode: Update command completed, but T3 Code still detects an outdated provider version.
and a persistent "Mac Studio failed" pill. Retrying gave the same result.
Diagnosis
The provider maintenance resolver picked the wrong install to update. It ran vp i -g @opencode/cli, which installed 2.1.2 into a Vite+ copy that never runs, and left the copy that does run at 2.1.1.
Machine layout:
- The OpenCode that actually runs is
~/.opencode/bin/opencode, a small sh wrapper that execs OpenCode 2 from a dedicated npm prefix (~/.opencode-v2/lib/node_modules/@opencode/cli). Version 2.1.1. - Vite+ 0.3.0 is installed and its bin dir
~/.local/share/vite-plus/bincomes before~/.opencode/binon the server's PATH. Vite+ also had anopencodeshim registered (~/.local/share/vite-plus/bins/opencode.json, created weeks earlier). ~/.config/vite-plus/config.jsonis{"shimMode": "system_first"}. In this mode a Vite+ shim runs the next matching executable on PATH, and only falls back to the Vite+-managed copy when there is none.
Sequence:
resolveCommandPath("opencode")returns~/.local/share/vite-plus/bin/opencode. Inpackages/provider-core/src/server/maintenanceResolver.ts,isVitePlusGlobalCommandPathmatches that path, andresolvePackageManagedProviderMaintenancereturnsupdateExecutable: "vp", updateArgs: ["i", "-g", "@opencode/cli"]. The cached advisory showed"updateCommand": "vp i -g @opencode/cli".vp i -g @opencode/clisucceeds:vp list -gshows@opencode/cli@2.1.2, and running the Vite+-managed binary directly printsopencode v2.1.2.- Verification runs
opencode --versionthrough the same shim. Because ofsystem_first, the shim delegates to~/.opencode/bin/opencode, which printsopencode v2.1.1, sorunCommandAndVerifyreports the version as still outdated.
Shim behavior, observed directly:
| 1 | PATH=<vp>/bin:/usr/bin:/bin <vp>/bin/opencode --version -> opencode v2.1.2 |
| 2 | PATH=<vp>/bin:~/.opencode/bin:/usr/bin:/bin <vp>/bin/opencode --version -> opencode v2.1.1 |
A path inside <VP_HOME>/bin does not prove Vite+ owns the executable that runs. With shimMode: system_first, or when no Vite+ global package provides the binary, the shim runs some other install. The resolver then updates the Vite+ copy, and vp i -g also creates a new, unused Vite+ install of the provider.
Possible fixes:
- Treat a Vite+ shim as Vite+-owned only when
vp env which <cmd>(or an equivalent check) resolves into<VP_HOME>/packages. Otherwise resolve the next PATH entry and classify that instead. - Skip the Vite+ branch when
shimModeissystem_firstand another candidate exists later on PATH. - When post-update verification fails, name the binary that was actually executed, so a shadowing install is visible to the user.
Not covered by the existing fix for #13010 (verification reads the installed CLI version, fe4ebc704): the installed CLI version is read correctly here, but from a different install than the one updated. main has no changes to maintenanceResolver.ts since this nightly.
Steps to reproduce
- On macOS, install Vite+ (0.3.0) with its bin dir first on PATH and set
vp env off(writes"shimMode": "system_first"). - Install OpenCode 2 at an older version outside Vite+, e.g. in a dedicated npm prefix exposed through a directory later on PATH (here
~/.opencode/bin). - Make Vite+ create an
opencodeshim in<VP_HOME>/bin, e.g.vp i -g @opencode/cli@<older version>. Withsystem_first, the shim keeps running the step 2 install. - Start T3 Code. OpenCode shows as outdated with update command
vp i -g @opencode/cli. - Click Update. The command succeeds, and T3 Code reports "Update command completed, but T3 Code still detects an outdated provider version."
Version
T3 Code 0.1.2-nightly.20261021.3457 (server t3 serve and the T3 Code (Nightly) desktop app on the affected machine; the UI was viewed from another Mac connected to it as a remote environment)
Environment
macOS 27.0.1 arm64, Node v26.12.0, Vite+ (vp) 0.3.0 with shimMode system_first, OpenCode 2.1.1 (@opencode/cli in a separate npm prefix) before the fix
Evidence
| 1 | # T3 provider cache (~/.t3/caches/opencode.json) after the failed update |
| 2 | "version": "2.1.1", |
| 3 | "versionAdvisory": { "status": "behind_latest", "currentVersion": "2.1.1", "latestVersion": "2.1.2", |
| 4 | "updateCommand": "vp i -g @opencode/cli", ... } |
| 5 | |
| 6 | # Server trace: two update attempts, all spans exit Success |
| 7 | 00:43:33 ProviderMaintenanceRunner.updateProvider -> runCommandAndVerify -> runCommand (7088 ms) |
| 8 | 00:45:05 ProviderMaintenanceRunner.runCommandAndVerify -> runCommand |
| 9 | |
| 10 | # Vite+ state after the update |
| 11 | $ vp list -g |
| 12 | @opencode/cli@2.1.2 24.22.0 opencode, opencode2 |
| 13 | $ cat ~/.config/vite-plus/config.json |
| 14 | { "shimMode": "system_first" } |
| 15 | |
| 16 | # Server PATH order (excerpt) |
| 17 | ...:~/.local/share/vite-plus/bin:...:~/.opencode/bin:... |
| 18 | |
| 19 | # Which binary runs |
| 20 | $ which -a opencode |
| 21 | ~/.local/share/vite-plus/bin/opencode |
| 22 | ~/.opencode/bin/opencode |
| 23 | $ ~/.local/share/vite-plus/bin/opencode --version # under the server PATH |
| 24 | opencode v2.1.1 |
| 25 | $ <vp packages>/@opencode/cli/<id>/bin/opencode --version |
| 26 | opencode v2.1.2 |
Related issues
#2714 (OpenCode update used npm regardless of install method), #5629 (Codex npm install -g loop against unverified installs), #10050 (mise shims made updates target the version manager), #18768 (Homebrew Grok update installed a second off-PATH copy). Same family, different cause: this one is Vite+ shims in system_first mode delegating to another install. #13010 is fixed, and its fix does not cover this case.
Fix applied or workaround
On the affected machine: ran the real install's updater (~/.opencode/bin/opencode upgrade, 2.1.1 → 2.1.2), then vp remove -g @opencode/cli to drop the Vite+ copy and shim so opencode resolves to the real install again.
Filed by
Claude Code (claude-opus-5-5) via npx t3@nightly triage