Skip to content

fix(cli): never let the update check block up/init (#418) - #422

Open
HusseinAdeiza wants to merge 1 commit into
genlayerlabs:v0.40-devfrom
HusseinAdeiza:fix/418-version-check-timeout
Open

HusseinAdeiza wants to merge 1 commit into
genlayerlabs:v0.40-devfrom
HusseinAdeiza:fix/418-version-check-timeout

Conversation

@HusseinAdeiza

Copy link
Copy Markdown

Summary

Fixes #418.

up and init await SimulatorService.checkCliVersion() as their very first step, before Docker is ever consulted. That method awaited update-check with no deadline and no try/catch, so the unauthenticated npm-registry request could take down the whole command.

Reproduced on v0.40-dev (commit 48d1223) with the registry blackholed:

$ node dist/index.js up --headless
- Checking CLI version...
/…/node_modules/update-check/index.js:125
		if (err.code && String(err.code).startsWith('4')) {
TypeError: Cannot read properties of undefined (reading 'code')
    at getMostRecent (node_modules/update-check/index.js:125:11)
    at async SimulatorService.checkCliVersion (dist/index.js:59025:20)
    at async StartAction.execute (dist/index.js:59385:5)
    at async Command.<anonymous> (dist/index.js:59500:5)

I measured each failure mode of update-check@1.5.4 against a stub registry:

condition before
healthy registry (control) resolves in ~40ms, no warning
registry unreachable / blackholed rejects after ~2s with TypeError
registry returns 5xx rejects, Error: Request failed with code 500
proxy returns an HTML login page with 200 rejects, SyntaxError: Unexpected token '<'
cache file left truncated by an interrupted run rejects, SyntaxError: Unexpected end of JSON input

There is a second, separate effect worth calling out. When the request times out, update-check calls reject() without destroying the request, so the socket stays open and the event loop never drains. The promise settles, but the process remains alive and idle. That matches the reported symptom more precisely than the crash above.

The fix

An upgrade notice is cosmetic, so it must not gate startup:

  • bound updateCheck() with CLI_VERSION_CHECK_TIMEOUT_MS (2s, exported from src/lib/config/simulator.ts next to the other timeout constants)
  • swallow every rejection and treat it as "no update information"
  • the deadline timer is unref'd so it cannot itself keep the process alive
  • the warning still prints when the check does succeed inside the deadline

After the fix, the same blackholed-registry run advances past Checking CLI version... into the Docker stage, which is where it belongs.

Tests

Six new cases in tests/services/simulator.test.ts, one per row of the table above plus the timeout path and a control asserting the warning still fires.

I confirmed they are not tautological: with the fix body reverted, 5 of the 6 fail, and all 6 pass with it restored.

Verification

  • npx vitest run — 818 passed
  • tsc --noEmit — clean for the touched files (the one pre-existing stakingWizard.test.ts error is unrelated and present on the base commit)
  • .github/scripts/validate-branch-policy.sh — ok for v0.40-dev as the active dev branch

tests/libs/keychainManager.test.ts fails locally because keytar's native binary is not built in this environment. That failure is pre-existing on the base commit and unrelated to this change; CI installs libsecret and builds it.

Per CONTRIBUTING.md the target is the v0.40-dev integration branch, not main, so this PR is opened against v0.40-dev.

Note on scope

I kept the fix in the CLI rather than bumping update-check, since the socket leak and the fragile err.code access are upstream bugs. The deadline plus the catch makes the CLI resilient to both without depending on an upstream release. Happy to revisit if maintainers would rather take the upgrade path.

)

`up` and `init` await `checkCliVersion()` as their first step, before Docker
is consulted. That method awaited `update-check` with no deadline and no
try/catch, so the unauthenticated npm registry request could abort the whole
command:

    $ node dist/index.js up --headless
    - Checking CLI version...
    TypeError: Cannot read properties of undefined (reading 'code')
        at getMostRecent (node_modules/update-check/index.js:125:11)
        at async SimulatorService.checkCliVersion (dist/index.js:59025:20)
        at async StartAction.execute (dist/index.js:59385:5)

Confirmed failure modes of update-check@1.5.4: an unreachable or blackholed
registry, a 5xx, a proxy login page served with 200, and a cache file left
truncated by an interrupted run. It also rejects on timeout without
destroying the request socket, so the promise settles while the event loop
stays held and the process hangs instead of exiting.

An upgrade notice is cosmetic and must not gate startup, so bound the call
with a short deadline and treat every failure as "no update information".
The warning still prints when the check succeeds in time.

Adds regression tests for each failure mode plus the timeout path.
@coderabbitai

coderabbitai Bot commented Sep 27, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: a9cb58cc-1c72-49a5-b030-20a165be0174

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

This branch has not been deployed

No deployments
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.

1 participant