Skip to content

fix(npm): prevent binary unavailability during auto-upgrade - #704

Open
lizhengfeng101 wants to merge 2 commits into
mainfrom
fix/npm-upgrade-binary-gap
Open

fix(npm): prevent binary unavailability during auto-upgrade#704
lizhengfeng101 wants to merge 2 commits into
mainfrom
fix/npm-upgrade-binary-gap

Conversation

@lizhengfeng101

@lizhengfeng101 lizhengfeng101 commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Add a binary cache fallback to ~/.opencodereview/bin/ so ocr remains available while the background auto-upgrade runs npm i -g
  • Before upgrading, the current binary is copied to the cache; resolveNativeBinary() uses it as a last resort when the platform package binary is missing
  • After a successful upgrade, the cache is refreshed with the new binary

Problem

When the background auto-upgrade runs npm i -g, npm removes the old platform package before installing the new one. During this gap window, ocr fails with "binary not found". On Windows, the running .exe cannot be deleted, so the upgrade fails entirely and can leave a permanently broken install.

Solution

A simple binary cache mechanism:

  1. scripts/update.js copies the current binary to ~/.opencodereview/bin/ before running npm i -g
  2. scripts/platform.js adds this cache path as the third fallback in resolveNativeBinary() (after platform package → legacy path → cache → null)

This ensures ocr always has a working binary to fall back on, even during the upgrade gap window or after a failed Windows upgrade.

Closes #703

Test plan

  • make check passes
  • make test passes
  • Manual: install old version → trigger upgrade → rapidly invoke ocr version during upgrade → should always succeed via cache fallback

Add a binary cache fallback mechanism to ensure ocr remains available
while the background auto-upgrade is running npm i -g.

Before the upgrade, the current binary is copied to
~/.opencodereview/bin/ as a safety net. resolveNativeBinary() now
checks this cache path as a last resort before returning null.

This fixes:
- Unix: the gap window where binary is deleted before new one installs
- Windows: broken installs when npm i -g fails due to file locks
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

🔍 OpenCodeReview found 2 issue(s) in this PR.

  • ✅ Successfully posted inline: 2 comment(s)

Comment thread scripts/platform.js Outdated
Comment on lines +58 to +60
const cachePath = path.join(
os.homedir(), ".opencodereview", "bin", BINARY_FILENAME
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[maintainability · medium]
The cache directory path ".opencodereview" is hardcoded here and also independently defined in scripts/update.js as path.join(os.homedir(), ".opencodereview"). If either location is changed without updating the other, the cache lookup will silently fail. Consider extracting this into a shared constant exported from platform.js (e.g., CACHE_DIR) and importing it in update.js to ensure consistency.

Comment thread scripts/update.js Outdated
const lockFile = path.join(stateDir, "update.lock");
const hintFile = path.join(stateDir, "update-available");

const CACHE_BIN_DIR = path.join(stateDir, "bin");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[maintainability · medium]
The cache directory path ~/.opencodereview/bin is constructed independently here and in platform.js (lines 58-59). If one location is updated but the other isn't, they will silently diverge, causing the cache to never be found or written correctly. Consider exporting CACHE_BIN_DIR (or a function like getCacheBinPath()) from platform.js and importing it here, so there's a single source of truth for the cache path.

Replace the simple binary cache with a proper staged binary mechanism:

- Add version.json metadata tracking (version, timestamp, platform)
- Add platform validation to prevent cross-platform misuse
- Add file integrity checks (exists, non-empty) in resolveStagedBinary()
- Notify users via dim stderr message when running from staged binary
- Refresh staged binary after successful upgrade for next-time protection
- Reuse STATE_DIR from platform.js to eliminate path duplication
- Always write version.json to avoid orphan binaries on disk

Resolution priority: platform package > staged binary > legacy path.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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

1 participant