You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[BUG] /update offers 2.0.7 on pacman-managed install, but upgrade cannot work (method undetected; GitHub release v2.0.7 missing) #49660
Install: distro package via pacman (pacman -S opencode, repo cachyos-extra-v3), binary at /usr/bin/opencode
OpenCode version: 2.0.5, channel=latest
What happens
The TUI home screen shows /update to install v2.0.7; running /update opens an "Update available" dialog (Skip / Update). The update server does return 2.0.7:
Pressing Update cannot succeed: Updater.method() (packages/cli/src/services/updater.ts @ v2.0.5) only detects ~/.opencode/bin (curl installs) and npm/pnpm/bun/yarn globals. A distro-package install at /usr/bin returns undefined → the upgrade aborts with "Could not detect the installation method".
The prompt is not suppressed for such unmanaged installs, even though the upgrade path is guaranteed to fail.
Second inconsistency — the advertised version isn't downloadable
The tag v2.0.7 exists, but there is no GitHub Release object for it: GET /repos/anomalyco/opencode/releases/tags/v2.0.7 → 404. The tag web page (/releases/tag/v2.0.7) returns 200, but shows only GitHub's auto-generated source archives — no binary assets.
The binary URL the install script downloads → 404: releases/download/v2.0.7/opencode-linux-x64.tar.gz (the same URL for v1.18.31 → 302, exists).
The install script's own existence check is fooled as well: it HEADs the tag web page (200), so --method curl proceeds and then dies on the asset download with HTTP 404.
Only @opencode/[email protected] on npm is actually published (dist-tag latest: 2.0.7); the legacy opencode-ai package remains on 1.18.31, and GitHub Releases currently carry only the 1.x line.
Root cause: the v2 branch's publish.yml has no gh release create/upload step at all — it deploys the update service, creates the git tag, and publishes to npm only. The dev branch (1.x line) still has them (packages/opencode/script/build.ts runs gh release upload v${version} ./dist/*.zip ./dist/*.tar.gz; workflow steps at lines ~205/~505). So the update API and git tags moved to the v2 world, while the GitHub Releases delivery channel that the install script (--method curl) relies on was left behind in 1.x.
Related defect in the same path
updater-action.tsaction() only checks sameRelease(current, latest) — there is no semver-gt guard — so any differing version (including an older one, cf. [v2] cli: update prompt recommends older version #47714) triggers an "update" notification.
Expected behavior
Suppress update prompts (or show "update via your package manager") when the install method is undetectable.
Only advertise versions whose artifacts are published to all supported upgrade channels (npm and GitHub Releases).
changed the title [-][BUG] Update prompt offers 2.0.7 to pacman-managed install, but upgrade is impossible (method undetected; GitHub release v2.0.7 missing)[/-][+][BUG] /update offers 2.0.7 on pacman-managed install, but upgrade cannot work (method undetected; GitHub release v2.0.7 missing)[/+]on Sep 18, 2026
Confirmed on v2.0.5 source, and one part of the report is narrower than stated: the v2 curl updater does not use GitHub Releases at all, so the missing v2.0.7 release only breaks the legacyopencode.ai/install script (dev branch), not /update.
What I ran against the v2.0.5 checkout (packages/cli/src/services/updater.ts, updater-action.ts executed as-is, types stripped):
inspect() -> action("2.0.5","2.0.7","notify") returns notify and the home screen shows the banner. method() is never consulted at this point.
Pressing Update calls apply() -> install() -> method(). method() checks only ~/.opencode/bin/opencode and a package.json two levels above process.execPath. For /usr/bin/opencode that is /usr/package.json, which does not exist, so installedPackage is undefined and method() returns undefined -> "Installation method not found".
Had method() returned curl, upgrade() fetches https://opencode.ai/v2/install, and that script resolves @opencode/[email protected] from registry.npmjs.org (200 above). The GitHub Releases dependency lives only in https://opencode.ai/install, which 307s to raw.githubusercontent.com/.../refs/heads/dev/install and does releases/download/v${version}/... (line 194 of that script). That is the 1.x installer; it cannot install 2.x from GitHub because nothing publishes assets there.
Workaround until this is fixed: the banner is driven by run(), which honours the policy file, so either
echo '{"update":"disable"}' > ~/.config/opencode/opencode.json # or "autoupdate": false
# or
export OPENCODE_DISABLE_AUTOUPDATE=1
readPolicy() only reads config.json / opencode.json / opencode.jsonc under $XDG_CONFIG_HOME/opencode (or $OPENCODE_CONFIG_DIR), not a project-level config. A manual /update still goes through check(), which ignores the policy, but it no longer nags.
Suggested fix in updater.ts: have run() call method() before returning {type:"available"} under notify/auto, and return undefined (with the existing "installation method not found" log) when it is undetected. That drops the banner for distro packages without touching the manual /update path. Detecting the package manager itself (pacman -Qo "$(realpath "$0")", dpkg -S, brew --prefix) would be a separate, nice-to-have step so the dialog can say "update via your package manager".
and method() still bails at if (!installedPackage) return before any package-manager probe, so a distro binary at /usr/bin/opencode can never be identified.
Two notes for whoever picks this up:
pacman -Qo <realpath(process.execPath)> returns ownership and the installed version in one call (/usr/bin/opencode is owned by opencode 2.1.3-1), and pacman -Si opencode with LC_ALL=C gives the sync-db candidate. dpkg -S / rpm -qf are the equivalents for the other distro packages.
Workaround in use here: a custom ~/.config/opencode/commands/update.md that overrides /update with a helper that picks repo vs AUR (pacman -Qm) and runs sudo pacman -S --needed opencode or yay -S opencode.
Thanks for the detailed report. I could reproduce the main problem.
To simulate a distro-package install, I copied the @opencode/cli release binary into a plain directory on PATH and removed the bun global install, so no package manager owns it. Then:
The home screen shows /update to install v2.2.0.
/update opens the "Update available" dialog with Skip / Update.
Pressing Update fails with "Could not detect the installation method. Update with your package manager or download the latest release."
I ran this on 2.1.4, not 2.0.5: the drive tooling can't run 2.0.5, and a release has to be older than the current latest (2.2.0) to be offered an update. The code that decides when to show the prompt is the same on the latest dev (950111f). The update check behind the home-screen hint still doesn't look at the install method; only the dialog's install step does. The recording and screenshots below show the whole flow, and the script below reproduces it.
On your second point: v2.0.7 still has no binary assets, but current v2 releases do. For example, releases/download/v2.2.0/opencode-linux-x64.tar.gz now resolves. So the GitHub Releases part looks addressed for newer versions.
// Reproduces #49660: on an install not managed by curl/npm/bun/... (e.g. a pacman package// binary in /usr/bin), the TUI still advertises an update, and /update cannot perform it.// Setup (simulates a distro-package binary; drive runs `opencode2` from PATH):// bun add -g @opencode/[email protected] # any release older than the current latest// mkdir -p /opt/usrbin && cp ~/.bun/install/global/node_modules/@opencode/cli/bin/opencode.exe /opt/usrbin/opencode2// bun remove -g @opencode/cli # so no package manager owns it// PATH=/opt/usrbin:$PATH opencode-drive run drive.tsimport{Effect}from"effect"import{OpenCodeDriver}from"opencode-drive"exportdefaultOpenCodeDriver.use({ ...(process.env.OC_DEV ? {opencode: {dev: process.env.OC_DEV}} : {}),tui: {recording: true}},({ ui })=>Effect.gen(function*(){yield*ui.waitFor("/update",{timeout: 60000})yield*ui.screenshot("home-update-hint")yield*ui.type("/update")yield*Effect.sleep("1 second")yield*ui.enter()yield*Effect.sleep("4 seconds")yield*ui.screenshot("update-dialog")yield*ui.enter()yield*Effect.sleep("6 seconds")yield*ui.screenshot("after-update")}),)
Run it with opencode-drive: opencode-drive run ./drive.ts. It drives opencode from your PATH; set OC_DEV to the path of an OpenCode checkout to run that from source instead.
Activity
[-][BUG] Update prompt offers 2.0.7 to pacman-managed install, but upgrade is impossible (method undetected; GitHub release v2.0.7 missing)[/-][+][BUG] /update offers 2.0.7 on pacman-managed install, but upgrade cannot work (method undetected; GitHub release v2.0.7 missing)[/+]aron-intframe commentedon Sep 18, 2026
Confirmed on v2.0.5 source, and one part of the report is narrower than stated: the v2
curlupdater does not use GitHub Releases at all, so the missingv2.0.7release only breaks the legacyopencode.ai/installscript (dev branch), not/update.What I ran against the v2.0.5 checkout (
packages/cli/src/services/updater.ts,updater-action.tsexecuted as-is, types stripped):So the actual sequence for a pacman install:
inspect()->action("2.0.5","2.0.7","notify")returnsnotifyand the home screen shows the banner.method()is never consulted at this point.apply()->install()->method().method()checks only~/.opencode/bin/opencodeand apackage.jsontwo levels aboveprocess.execPath. For/usr/bin/opencodethat is/usr/package.json, which does not exist, soinstalledPackageisundefinedandmethod()returnsundefined-> "Installation method not found".method()returnedcurl,upgrade()fetcheshttps://opencode.ai/v2/install, and that script resolves@opencode/[email protected]from registry.npmjs.org (200 above). The GitHub Releases dependency lives only inhttps://opencode.ai/install, which 307s toraw.githubusercontent.com/.../refs/heads/dev/installand doesreleases/download/v${version}/...(line 194 of that script). That is the 1.x installer; it cannot install 2.x from GitHub because nothing publishes assets there.Workaround until this is fixed: the banner is driven by
run(), which honours the policy file, so eitherreadPolicy()only readsconfig.json/opencode.json/opencode.jsoncunder$XDG_CONFIG_HOME/opencode(or$OPENCODE_CONFIG_DIR), not a project-level config. A manual/updatestill goes throughcheck(), which ignores the policy, but it no longer nags.Suggested fix in
updater.ts: haverun()callmethod()before returning{type:"available"}undernotify/auto, and returnundefined(with the existing "installation method not found" log) when it is undetected. That drops the banner for distro packages without touching the manual/updatepath. Detecting the package manager itself (pacman -Qo "$(realpath "$0")",dpkg -S,brew --prefix) would be a separate, nice-to-have step so the dialog can say "update via your package manager".Acidburn0x90 commentedon Oct 25, 2026
Same failure on 2.1.3 with the Arch
extrapackage, so it survived 2.0.5 → 2.1.3:packages/cli/src/services/updater.tsondevis unchanged on this point:and
method()still bails atif (!installedPackage) returnbefore any package-manager probe, so a distro binary at/usr/bin/opencodecan never be identified.Two notes for whoever picks this up:
pacman -Qo <realpath(process.execPath)>returns ownership and the installed version in one call (/usr/bin/opencode is owned by opencode 2.1.3-1), andpacman -Si opencodewithLC_ALL=Cgives the sync-db candidate.dpkg -S/rpm -qfare the equivalents for the other distro packages.sudo pacman -Syucannot authenticate from there. Detection plus "update via your package manager, then restart" is probably the realistic scope; feat(desktop): honor OPENCODE_DISABLE_AUTOUPDATE in the updater #55155 and fix(nix): disable the self-updater in the flake build #57979 already take that direction for the env-var and nix cases.Workaround in use here: a custom
~/.config/opencode/commands/update.mdthat overrides/updatewith a helper that picks repo vs AUR (pacman -Qm) and runssudo pacman -S --needed opencodeoryay -S opencode.opencodejr commentedon Oct 28, 2026
Thanks for the detailed report. I could reproduce the main problem.
To simulate a distro-package install, I copied the
@opencode/clirelease binary into a plain directory onPATHand removed the bun global install, so no package manager owns it. Then:/update to install v2.2.0./updateopens the "Update available" dialog with Skip / Update.I ran this on 2.1.4, not 2.0.5: the drive tooling can't run 2.0.5, and a release has to be older than the current latest (2.2.0) to be offered an update. The code that decides when to show the prompt is the same on the latest
dev(950111f). The update check behind the home-screen hint still doesn't look at the install method; only the dialog's install step does. The recording and screenshots below show the whole flow, and the script below reproduces it.On your second point:
v2.0.7still has no binary assets, but current v2 releases do. For example,releases/download/v2.2.0/opencode-linux-x64.tar.gznow resolves. So the GitHub Releases part looks addressed for newer versions.Related issues:
recording.mp4
Reproduction script (drive.ts)
Run it with opencode-drive:
opencode-drive run ./drive.ts. It drivesopencodefrom yourPATH; setOC_DEVto the path of an OpenCode checkout to run that from source instead.