# OpenCode update targets a Vite\+ shim that delegates to another install \(shimMode system_first\), then reports "still outdated" · Issue \#22741 · pingdotgg/t3code

[View on GitCafe](https://git.cafe/pingdotgg/t3code/issues/22741)

Repository: [pingdotgg/t3code](https://git.cafe/pingdotgg/t3code)

Visibility: public

State: backlog

Priority: 0

## Description

[Discussion and activity](https://git.cafe/pingdotgg/t3code/issues/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/bin` comes **before** `~/.opencode/bin` on the server's PATH. Vite+ also had an `opencode` shim registered (`~/.local/share/vite-plus/bins/opencode.json`, created weeks earlier).
- `~/.config/vite-plus/config.json` is `{"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:

1. `resolveCommandPath("opencode")` returns `~/.local/share/vite-plus/bin/opencode`. In `packages/provider-core/src/server/maintenanceResolver.ts`, `isVitePlusGlobalCommandPath` matches that path, and `resolvePackageManagedProviderMaintenance` returns `updateExecutable: "vp", updateArgs: ["i", "-g", "@opencode/cli"]`. The cached advisory showed `"updateCommand": "vp i -g @opencode/cli"`.
2. `vp i -g @opencode/cli` succeeds: `vp list -g` shows `@opencode/cli@2.1.2`, and running the Vite+-managed binary directly prints `opencode v2.1.2`.
3. Verification runs `opencode --version` through the same shim. Because of `system_first`, the shim delegates to `~/.opencode/bin/opencode`, which prints `opencode v2.1.1`, so `runCommandAndVerify` reports the version as still outdated.

Shim behavior, observed directly:

```
PATH=<vp>/bin:/usr/bin:/bin                 <vp>/bin/opencode --version  -> opencode v2.1.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 `shimMode` is `system_first` and 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

1. On macOS, install Vite+ (0.3.0) with its bin dir first on PATH and set `vp env off` (writes `"shimMode": "system_first"`).
2. 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`).
3. Make Vite+ create an `opencode` shim in `<VP_HOME>/bin`, e.g. `vp i -g @opencode/cli@<older version>`. With `system_first`, the shim keeps running the step 2 install.
4. Start T3 Code. OpenCode shows as outdated with update command `vp i -g @opencode/cli`.
5. 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

```shell
# T3 provider cache (~/.t3/caches/opencode.json) after the failed update
"version": "2.1.1",
"versionAdvisory": { "status": "behind_latest", "currentVersion": "2.1.1", "latestVersion": "2.1.2",
                     "updateCommand": "vp i -g @opencode/cli", ... }

# Server trace: two update attempts, all spans exit Success
00:43:33 ProviderMaintenanceRunner.updateProvider -> runCommandAndVerify -> runCommand (7088 ms)
00:45:05 ProviderMaintenanceRunner.runCommandAndVerify -> runCommand

# Vite+ state after the update
$ vp list -g
@opencode/cli@2.1.2   24.22.0   opencode, opencode2
$ cat ~/.config/vite-plus/config.json
{ "shimMode": "system_first" }

# Server PATH order (excerpt)
...:~/.local/share/vite-plus/bin:...:~/.opencode/bin:...

# Which binary runs
$ which -a opencode
~/.local/share/vite-plus/bin/opencode
~/.opencode/bin/opencode
$ ~/.local/share/vite-plus/bin/opencode --version      # under the server PATH
opencode v2.1.1
$ <vp packages>/@opencode/cli/<id>/bin/opencode --version
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`

