Skip to content

cli: update via bun global install leaves stale entry-point binary; old version keeps running #60183

Open

Description

@akashtattva

Summary

On Windows, updating OpenCode through Bun's global package install updates the package files but leaves the entry-point binary (@opencode/cli/bin/opencode.exe) as a stale hardlink to the old platform binary. The CLI keeps running the old version even though the update "succeeds", and opencode --version reports the old version, so it looks like the update failed and is hard to notice.

Environment

  • opencode version: 2.1.3 remained after updating to 2.2.0 (now 2.2.0 after manual fix)
  • OS: Windows_NT 10.0.18363 (win32 x64), Git Bash (mintty / xterm-256color)
  • Shell: bash.exe (Git for Windows); ComSpec = cmd.exe
  • Install/channel: Bun global package (@opencode/[email protected] per bun pm ls -g), shim at ~/.bun/bin/opencode.exe pointing to ../node_modules/@opencode/cli/bin/opencode.exe
  • Active plugins: None

Reproduction

  1. Install OpenCode via Bun global package (bun add -g @opencode/cli on Windows). Bun resolves the shim to C:\Users\<user>\node_modules\@opencode\cli\bin\opencode.exe, which is hardlinked (nlink=3) to one of the platform packages — in my case @opencode/cli-windows-x64-baseline/bin/opencode.exe (same size, link count 3).
  2. Update to a new version (exact update command not captured — packages were updated to @opencode/[email protected]; the TUI had shown the "update available" notice).
  3. Observe: all three package.json files say 2.2.0, and @opencode/cli-windows-x64/bin/opencode.exe is freshly updated, but:
    • @opencode/cli/bin/opencode.exe (the entry point the shim launches) is untouched: dated Oct 23, 246,810,504 bytes, still v2.1.3, still hardlinked to the stale cli-windows-x64-baseline/bin/opencode.exe
    • @opencode/cli-windows-x64-baseline/bin/opencode.exe is likewise stale
    • opencode --version → v2.1.3, and the background service runs v2.1.3 (/api/info → version: 2.1.3) even though the update completed

State before the manual fix:

/c/Users/hp/node_modules/@opencode/cli/bin/opencode.exe
  Oct 23 14:35, 246810504 bytes, links=3, reports v2.1.3   <- what opencode.exe runs
/c/Users/hp/node_modules/@opencode/cli-windows-x64/bin/opencode.exe
  Oct 28 14:27, 253303688 bytes, links=1, reports v2.2.0   <- fresh, never used
/c/Users/hp/node_modules/@opencode/cli-windows-x64-baseline/bin/opencode.exe
  Oct 23 14:35, 246810504 bytes, links=3, reports v2.1.3   <- stale, linked with entry point

Expected Behavior

After a successful update, the binary that opencode (the Bun shim → @opencode/cli/bin/opencode.exe) actually launches is the new version, and opencode --version and the running service both report it.

Actual Behavior

The update completes and the package metadata shows the new version, but execution never changes: every opencode invocation (CLI, TUI→service) keeps running v2.1.3. opencode --version also reports the old version, which hides the problem from the user.

Workaround (what fixed it)

rm C:/Users/hp/node_modules/@opencode/cli/bin/opencode.exe
cp C:/Users/hp/node_modules/@opencode/cli-windows-x64/bin/opencode.exe \
   C:/Users/hp/node_modules/@opencode/cli/bin/opencode.exe
opencode service restart

(Deleting the file first is important: overwriting a hardlinked file in place would modify the platform package too.) After this, opencode --version → 2.2.0 and /api/info → version: 2.2.0. The stale cli-windows-x64-baseline binary remains and probably needs a forced reinstall to clear.

Additional Context

  • Possibly related to Bun's hardlink/dedupe behavior on Windows rather than opencode itself, but the updater should ideally detect or repair a mismatch between the reported package version and the entry-point binary's version — or at minimum, opencode upgrade should refuse to claim success when the launched binary still reports the old version.
  • Shell note: opencode api get /api/info fails under Git Bash because MSYS rewrites /api/info into a Windows path (C:/Program Files/Git/api/info) before it reaches the CLI. MSYS_NO_PATHCONV=1 avoids it. Minor, but it cost some diagnosis time and may be worth a note in the docs.

Activity

  1. opencodejr commented on Oct 29, 2026

    @opencodejr
    Contributor

    Thanks for the detailed report and the file listings. I tried this on Linux x64 with a global Bun install. I installed @opencode/[email protected] with --trust, then updated to 2.2.0 three ways: the updater's own command (bun install --global --trust ...), opencode upgrade 2.2.0 --method bun, and a plain bun add -g @opencode/[email protected]. Each time the entry bin/opencode.exe was re-linked to the new platform binary, the -baseline package was updated too, and opencode --version reported v2.2.0. So the problem seems to be specific to Windows, for example the lock Windows keeps on a running opencode.exe while the service or TUI is open, or how Bun handles global installs there. Our sandbox can't test that, so a maintainer with a Windows machine will need to confirm it.

    If you can, these would help:

    • the exact command or UI action you used to update (TUI notice, opencode upgrade, bun update -g, bun add -g, …), and whether OpenCode or its background service was running at the time
    • the output of that update command, especially anything from postinstall
    • your Bun version (bun --version)

    Related: #51386 (Bun upgrade on Windows reports success but leaves the old binary on PATH) and #52152 (the upgrade reports success but the running binary is not replaced).

  2. akashtattva commented on Oct 29, 2026

    @akashtattva
    Author

    Additional data points:

    • Bun: 1.3.14 (Windows 10, x64)
    • Yes, OpenCode and its background service were running during the update (the service had been started by the old v2.1.3 binary). Unfortunately the exact update command wasn't captured.

    Interesting detail that may weaken the file-lock theory: the fresh @opencode/cli-windows-x64/bin/opencode.exe was written successfully (Oct 28 14:27) while the old binary was still running — Windows didn't block Bun from creating a new exe alongside the running one. Nothing needed to be replaced in place. What stayed stale was:

    1. @opencode/cli/bin/opencode.exe — the entry-point copy the shim launches, hardlinked (nlink=3) to
    2. @opencode/cli-windows-x64-baseline/bin/opencode.exe

    Both kept the identical old content (same size, Oct 23 mtime, reports v2.1.3) even though all three package.json files say 2.2.0. So it looks less like a lock failure and more like Bun reused deduped/cached content for that shared hardlink instead of replacing it (both stale files are the same inode; the third link is presumably the bun install cache at ~/.bun/install/cache).

    Consistent with that: my manual fix was rm the entry-point copy + cp the fresh x64 exe over it, done while the old service process was still running — i.e. an unlink + create (not an in-place overwrite) worked fine on Windows. The -baseline package's exe is still v2.1.3 to this day, presumably still sharing its content with the cache.

    One more Windows-specific quirk from this setup, possibly relevant: bun pm bin -g returns ~/.bun/bin, but Bun's global node_modules actually materialized at node_modules directly under the home directory (C:\Users\hp\node_modules, verified via bun pm ls -g --verbose and by running the packages). The shim spec points at ..\node_modules\@opencode\cli\bin\opencode.exe, so the shim resolves against that global root rather than ~/.bun/node_modules (which doesn't exist). I don't know whether that layout is standard or a side effect of something on this machine, but it seems worth knowing if the relinking logic assumes a layout that doesn't hold here.

    Let me know if it would help to run a controlled repro: e.g. reinstall @opencode/[email protected], stop the service, update via opencode upgrade, and capture the full update command output including postinstall.

  3. akashtattva commented on Oct 29, 2026

    @akashtattva
    Author

    Small correction on my earlier comment: the exact update method was the /update command inside the OpenCode CLI (TUI) — so opencode's own updater drove the update, not a manual bun invocation. I was inside the TUI at the time, so the updater's own output (including any postinstall steps) scrolled by in the session and wasn't captured, sorry.

    Repro path for a Windows maintainer should therefore be:

    1. Have @opencode/cli installed globally via Bun (shim at ~/.bun/bin/opencode.exe resolving to node_modules/@opencode/cli/bin/opencode.exe)
    2. Open the TUI, run /update
    3. After it reports success, opencode --version still reports the old version; the entry-point binary (and cli-windows-x64-baseline/bin/opencode.exe, which shares its inode) is unchanged while cli-windows-x64/bin/opencode.exe and all package.json files show the new version
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