OpenCodeReview Version
v1.8.5 (reproduced on current main, commit 3b9c5e7)
Operating System
- macOS (Apple Silicon)
- Windows
- Linux (x86_64)
(All three platforms are affected; Windows is the worst case.)
Installation Method
npm (global)
LLM Provider
Other OpenAI-compatible endpoint
Bug Description
When ocr is installed globally via npm, the ocr command becomes unavailable while the background auto-upgrade runs (scripts/update.js executing npm i -g), failing with:
[ERROR] OpenCodeReview binary not found. Run: npm install -g @alibaba-group/open-code-review
The root cause is that the auto-upgrade uses a "delete-then-install" approach, leaving a window where the native binary is missing on disk. Any ocr invocation during that window fails because resolveNativeBinary() returns null.
Upgrade flow (bin/ocr.js + scripts/update.js):
-
bin/ocr.js:43-51 — on every ocr run, scripts/update.js is spawned as a detached background process.
-
scripts/update.js:164 — when a newer version is found, it runs spawnSync("npm", ["i", "-g", ${pkgName}@${latestVersion}]) to reinstall globally.
- npm reinstalls by first removing the old platform package
@alibaba-group/ocr-<platform> (which contains bin/opencodereview), then downloading and installing the new one.
- During the "remove old → install new" gap in step 3,
resolveNativeBinary() in scripts/platform.js:36 finds neither the platform-package binary nor the legacy bin/opencodereview path, and returns null.
- This hits the
if (!resolved) branch at bin/ocr.js:12-17, which prints the error and exit(1).
The window length depends on network download speed (the platform package ships a multi-MB binary), and can last from a few seconds to tens of seconds.
Additional Windows-only problem: ocr.js:54 immediately spawnSyncs the native binary right after spawning the detached upgrader. This means opencodereview.exe is still running when the background npm i -g tries to delete/replace it. Windows refuses to remove a running .exe (EBUSY/EPERM), so the upgrade fails and can leave the install in a broken "old binary deleted, new binary not yet written" state, making ocr permanently unavailable until a manual npm i -g repairs it.
Steps to Reproduce
# 1. Install an older version globally
$ npm i -g @alibaba-group/open-code-review@<old-version>
# 2. Wait for / trigger the background upgrade (run any ocr command, 18-min cooldown elapsed)
$ ocr version
# 3. While the background npm i -g is still running, keep invoking ocr
# (during the gap between old binary removal and new binary install)
$ ocr version
[ERROR] OpenCodeReview binary not found. Run: npm install -g @alibaba-group/open-code-review
On Windows it's easiest to reproduce: keep an ocr review running for a while (binary in execution) while the background upgrade triggers — npm i -g then fails because the file is locked.
Expected Behavior
Auto-upgrade should never make ocr unavailable at any point in time. The upgrade should be transparent to the user — either keep the old binary until the new one is verified ready (atomic replace / install-then-remove), or on Windows detect that the binary is in use and wait for the foreground process to exit before replacing, rather than failing outright and leaving a broken install behind.
Logs / Error Output
$ ocr version
[ERROR] OpenCodeReview binary not found. Run: npm install -g @alibaba-group/open-code-review
On Windows, when npm i -g fails it also writes the ~/.opencodereview/update-available hint (scripts/update.js:173), causing every subsequent ocr run to print the upgrade nudge (compounds with #697).
Additional Context
Relevant code locations:
bin/ocr.js:43-51 — detached background spawn of update.js
bin/ocr.js:12-17 — hard-fail branch when binary is not found
bin/ocr.js:54 — concurrent background upgrade and foreground binary execution
scripts/update.js:164 — npm i -g global reinstall (non-atomic delete-then-install)
scripts/platform.js:36-58 — resolveNativeBinary() lookup logic
Related issue: #697 (upgrade nudge shown even when already on the latest version) — this compounds with the present bug.
Possible fix directions:
- Have the background upgrade download to a temporary location first and do an atomic
rename(2) swap after checksum verification, eliminating the delete-then-install gap.
- On Windows, detect that the binary is in use and wait for the foreground process to exit before replacing (or use a post-restart self-replacement / launcher strategy).
- During the gap window, when
resolveNativeBinary() can't find the binary, fall back to a cached copy of the last binary (e.g. kept under ~/.opencodereview/) instead of hard-failing.
OpenCodeReview Version
v1.8.5(reproduced on current main, commit3b9c5e7)Operating System
(All three platforms are affected; Windows is the worst case.)
Installation Method
npm (global)
LLM Provider
Other OpenAI-compatible endpoint
Bug Description
When
ocris installed globally via npm, theocrcommand becomes unavailable while the background auto-upgrade runs (scripts/update.jsexecutingnpm i -g), failing with:The root cause is that the auto-upgrade uses a "delete-then-install" approach, leaving a window where the native binary is missing on disk. Any
ocrinvocation during that window fails becauseresolveNativeBinary()returnsnull.Upgrade flow (
bin/ocr.js+scripts/update.js):bin/ocr.js:43-51— on everyocrrun,scripts/update.jsis spawned as a detached background process.scripts/update.js:164— when a newer version is found, it runsspawnSync("npm", ["i", "-g",${pkgName}@${latestVersion}])to reinstall globally.@alibaba-group/ocr-<platform>(which containsbin/opencodereview), then downloading and installing the new one.resolveNativeBinary()inscripts/platform.js:36finds neither the platform-package binary nor the legacybin/opencodereviewpath, and returnsnull.if (!resolved)branch atbin/ocr.js:12-17, which prints the error andexit(1).The window length depends on network download speed (the platform package ships a multi-MB binary), and can last from a few seconds to tens of seconds.
Additional Windows-only problem:
ocr.js:54immediatelyspawnSyncs the native binary right after spawning the detached upgrader. This meansopencodereview.exeis still running when the backgroundnpm i -gtries to delete/replace it. Windows refuses to remove a running.exe(EBUSY/EPERM), so the upgrade fails and can leave the install in a broken "old binary deleted, new binary not yet written" state, makingocrpermanently unavailable until a manualnpm i -grepairs it.Steps to Reproduce
On Windows it's easiest to reproduce: keep an
ocr reviewrunning for a while (binary in execution) while the background upgrade triggers —npm i -gthen fails because the file is locked.Expected Behavior
Auto-upgrade should never make
ocrunavailable at any point in time. The upgrade should be transparent to the user — either keep the old binary until the new one is verified ready (atomic replace / install-then-remove), or on Windows detect that the binary is in use and wait for the foreground process to exit before replacing, rather than failing outright and leaving a broken install behind.Logs / Error Output
On Windows, when
npm i -gfails it also writes the~/.opencodereview/update-availablehint (scripts/update.js:173), causing every subsequentocrrun to print the upgrade nudge (compounds with #697).Additional Context
Relevant code locations:
bin/ocr.js:43-51— detached background spawn ofupdate.jsbin/ocr.js:12-17— hard-fail branch when binary is not foundbin/ocr.js:54— concurrent background upgrade and foreground binary executionscripts/update.js:164—npm i -gglobal reinstall (non-atomic delete-then-install)scripts/platform.js:36-58—resolveNativeBinary()lookup logicRelated issue: #697 (upgrade nudge shown even when already on the latest version) — this compounds with the present bug.
Possible fix directions:
rename(2)swap after checksum verification, eliminating the delete-then-install gap.resolveNativeBinary()can't find the binary, fall back to a cached copy of the last binary (e.g. kept under~/.opencodereview/) instead of hard-failing.