Skip to content

cli: upgrade reports success but the running binary is not replaced when another copy is registered with the package manager #52152

Closed

Description

@Raed2180416

Description

opencode upgrade reports success but the running binary is never replaced.

When a second copy of the CLI is registered with a package manager — a custom npm prefix, or a manually linked directory — method() matches that manager from its global package list, and the upgrade runs install --global against that other copy. The command prints Upgrade complete and exits 0, while the binary that was actually executing stays on its old version.

Reproduced on a real install:

BEFORE: running=opencode v2.0.19   npm-global=opencode v2.0.16

$ opencode upgrade 2.0.16
●  Using method: npm
●  From 2.0.19 → 2.0.16
◇  Upgrade complete

AFTER : running=opencode v2.0.19   npm-global=opencode v2.0.16

The running binary is still 2.0.19. There is no error and no non-zero exit, so the failure is silent.

Impact

  • /update and upgrade appear to succeed while doing nothing.
  • update: auto in config reinstalls on every check and never advances.
  • Multiple installs on PATH (a custom prefix plus the default global prefix) are enough to trigger it.

This is a likely root cause for the older "upgrade doesn't take" reports where the reporter had more than one installation (#15248, #11021, #5375).

Steps to reproduce

  1. Install the CLI into a custom prefix, e.g. npm install --prefix ~/.local @opencode/cli.
  2. Also have the same package registered in the default global prefix.
  3. Put the custom-prefix copy first on PATH and run it.
  4. Run opencode upgrade <version>.
  5. Observe "Upgrade complete", then opencode --version still shows the old version.

OpenCode version

2.0.19

Operating System

Linux

Terminal

xterm

Activity

  1. github-actions commented on Sep 29, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

  2. coygeek commented on Oct 3, 2026

    @coygeek

    Also reproduced on OpenCode 2.0.22, macOS arm64, with npm 12.0.2 and Node.js v22.23.2.

    In this case, @opencode/cli is installed globally in a custom npm prefix, and npm’s default global prefix does not contain the package. Running opencode2 update 2.0.22 exits with code 1:

    Could not detect the installation method. Pass --method to choose how to upgrade OpenCode.
    

    The same failure occurred on 2.0.18. Installing 2.0.22 manually with npm and the original explicit --prefix succeeded, but the built-in updater still fails afterward.

    This appears to be another symptom of the prefix-selection problem described here. A fix should cover both layouts: a custom-prefix installation with no default-prefix copy, and a custom-prefix installation alongside a default-prefix copy.

  3. opencodejr commented on Oct 28, 2026

    @opencodejr
    Contributor

    Thanks for the detailed report. I was able to reproduce this.

    Setup: @opencode/[email protected] installed with npm install -g (default prefix /usr/local), and @opencode/[email protected] with npm install -g --prefix ~/.local, with ~/.local/bin first on PATH. Running opencode upgrade 2.0.17 printed Using method: npm and Upgrade complete and exited 0. Afterwards the running copy was still v2.0.19, and the default-prefix copy had changed to v2.0.17.

    The same thing happens with the latest release, 2.2.0 (2.0.16 global, upgrading to 2.1.4). On the latest dev (86ce19d), the code that detects the install method and runs the upgrade is unchanged from 2.2.0. The script below reproduces it.

    Related: your PR #52149, which takes the approach of only using a package manager whose global root contains the running binary.

    Reproduction script (repro.sh)
    #!/usr/bin/env bash
    # Reproduces #52152: `opencode upgrade` upgrades a different npm-global copy, not the running binary.
    # Usage: RUNNING=2.0.19 OTHER=2.0.16 TARGET=2.0.17 bash repro.sh
    set -u
    RUNNING=${RUNNING:-2.0.19}; OTHER=${OTHER:-2.0.16}; TARGET=${TARGET:-2.0.17}
    PREFIX=${PREFIX:-$HOME/.local}
    npm install -g "@opencode/cli@$OTHER" >/dev/null 2>&1                      # copy in the default global prefix
    npm install -g --prefix "$PREFIX" "@opencode/cli@$RUNNING" >/dev/null 2>&1   # copy in a custom prefix
    DEFAULT_BIN="$(npm config get prefix)/bin/opencode"
    export PATH="$PREFIX/bin:$PATH"                                               # custom-prefix copy first on PATH
    echo "BEFORE: running=$(opencode --version) ($(command -v opencode))  npm-global=$($DEFAULT_BIN --version)"
    opencode upgrade "$TARGET" </dev/null 2>&1 | sed 's/\x1b\[[0-9;?]*[A-Za-z]//g' | grep -E 'method|From|complete|failed|Done'
    echo "exit=${PIPESTATUS[0]}"
    echo "AFTER : running=$(opencode --version)  npm-global=$($DEFAULT_BIN --version)"

    Run it: bash repro.sh

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions