Repository navigation
[Bug]: OpenCode update reports "still needs an update" after a successful upgrade because verification reads the running server version #13010
Description
Activity
Triage
Confirmed on
mainat5a61f50cc. This is not a duplicate of #5629, #3550, or #8280. Those share the "Provider still needs an update" toast, but the update command there did not actually update the binary T3 Code later probed. Hereopencode upgradeis the right command, it exits 0, andopencode --versionis already the new build. Only the version used for verification is stale.For a local OpenCode install (Server URL empty), post-update verification calls
refreshInstance, which runscheckOpenCodeProviderStatus:opencode --versionstarts a new process and parses the on-disk version (OpenCodeProvider.tsaround the--versionprobe).- Inventory is loaded through
OpenCodeServerOwner.withServer. If the owned child is still running, that handle is reused. It is only closed afterOPENCODE_SERVER_IDLE_TTL("30 seconds") once nothing is borrowing it, and the verification probe itself is a borrower, so it resets that timer. A live turn keeps the old process until the turn ends and the idle timeout fires (OpenCodeServerOwner.ts). - The handle's
versionis whatever/global/healthreturned when that process was spawned (verifyOpenCodeServerVersioninstartOpenCodeServerProcess). It is not read again on the next borrow.opencode upgradereplaces the binary; the running process keeps the old code. - On a successful inventory, that startup version overwrites the CLI probe (
version = inventoryExit.value.version). The snapshot,~/.t3/caches/opencode.json, and the version advisory all follow the old server.behind_latestmakesProviderMaintenanceRunnerrecordstatus: "unchanged", and the client shows "Provider still needs an update" / "OpenCode still appears outdated."
That overwrite came from #8480, which started reporting the serving process instead of the CLI. That matches an external server, and it matches a local server at spawn time. It is wrong for the window after a successful upgrade of a T3-owned helper.
The native update path is doing the right thing on this install.
isOpenCodeNativeCommandPathmatches a real path under~/.opencode/bin/opencode, and the command that runs is the resolved binary plusupgrade(OpenCodeDriver.ts). The cached~/.local/bin/opencode upgradeis that branch, not the old npm guess. #9325 (which closed #5629) only selects the installer that owns the binary. It does not restart or ignore a stale ownedopencode serve. #3550 was closednot_plannedon a Codex/Bun hypothesis. #8280 was a Claude/Homebrew hang where the suggested upgrade was already a no-op. None of those change this path.The reported self-heal matches the owner: once the old child is idle long enough to be replaced, the next health check is the new binary and the advisory clears. Refreshing after that idle period, or restarting T3 Code, is a valid workaround. The install is already updated.
A fix should not kill a helper that a turn is still borrowing. After
opencode upgradeexits 0, verification for a T3-owned local server should treat the CLI probe as the installed version when it is newer than the cached server version, or restart the owned server only when this probe is the sole borrower and then re-read/global/health. An in-flight turn can keep the old process until it goes idle.- addedbugSomething is broken or behaving incorrectly.Something is broken or behaving incorrectly.via-triageFiled through npx t3 triageFiled through npx t3 triage
on Sep 22, 2026
Before submitting
Area
apps/server
Steps to reproduce
opencode servehelper. Leave that helper running.opencode upgraderuns, exits 0, and replaces the binary on disk.Provider still needs an update/OpenCode still appears outdatedeven though the CLI on disk is now the latest version.Expected behavior
After the update command exits 0, T3 Code should verify the newly installed version and show the success state. For a local OpenCode server that T3 Code owns, it should restart or invalidate that helper before re-reading the version, or fall back to the version from the
opencode --versionprobe it just ran.Actual behavior
The post-update verification reads the version from the already-running
opencode servechild instead of the updated CLI.opencode upgradereplaces the binary but the running process keeps the old code in memory, so/global/healthkeeps returning the old version. The advisory staysbehind_latest, the update state becomesunchanged, and the client rendersProvider still needs an update.Relevant code on main:
apps/server/src/provider/Layers/OpenCodeProvider.tsprobesopencode --version, then overwrites that result with the server handle's version at line 535:version = inventoryExit.value.version;OpenCodeServerOwner.withServer(...), which reuses any live server and only restarts it afterOPENCODE_SERVER_IDLE_TTL = "30 seconds"(apps/server/src/provider/OpenCodeServerOwner.ts).apps/server/src/provider/providerMaintenanceRunner.tscomputesstillOutdatedfrom that refreshed snapshot and recordsstatus: "unchanged"at line 416, which produces the toast.Timeline from my machine (local time, 2026-09-21, OpenCode 1.18.31 to 1.18.32, native install, no npm):
opencode upgradeexits 0 after about 15 s and the binary on disk becomes 1.18.32.version = 1.18.31in~/.t3/caches/opencode.json, even thoughopencode --versionreports 1.18.32 at the same moment.unchanged.opencode servechildren start. Both report 1.18.32 on/global/health, so the reported state self-corrects once the helper is replaced.Trace:
ProviderMaintenanceRunner.runCommandAndVerify, traceIdb345808a7791d2cd9d02b630872e0cbc.Note: this is the same visible symptom as #5629 and #3550 (Codex) and #8280 (Claude Code), but a different root cause. The binary install path is detected correctly here, the upgrade succeeds, and the CLI probe returns the new version. Only the server version used for verification is stale.
Impact
Minor bug or occasional failure
Version or commit
T3 Code 0.0.42 (client
APP_VERSIONfrom the running bundle)Environment
Windows host with a WSL2 (Ubuntu) environment. OpenCode provider enabled with the default local server (Server URL empty). OpenCode upgraded from 1.18.31 to 1.18.32 via
opencode upgrade, native install at~/.opencode/bin/opencode.Logs or stack traces
Screenshots, recordings, or supporting files
Toast text:
Provider still needs an update/OpenCode still appears outdated. Check provider settings for details.with a Settings button.Workaround
Refresh provider status after the local helper has been idle for about 30 seconds (it restarts from the new binary), or restart T3 Code. The update itself is already applied.