Skip to content

ocr command becomes unavailable during npm auto-upgrade (binary gap window + Windows file lock) #703

Description

@stay-foolish-forever

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):

  1. bin/ocr.js:43-51 — on every ocr run, scripts/update.js is spawned as a detached background process.
  2. scripts/update.js:164 — when a newer version is found, it runs spawnSync("npm", ["i", "-g", ${pkgName}@${latestVersion}]) to reinstall globally.
  3. npm reinstalls by first removing the old platform package @alibaba-group/ocr-<platform> (which contains bin/opencodereview), then downloading and installing the new one.
  4. 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.
  5. 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:

  1. 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.
  2. 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).
  3. 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.

Activity

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

Metadata

Metadata

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