Repository navigation
Fix hosted npm ignoring omit-lockfile-registry-resolved (#1871) - #1872
Mikola Lysenko (mikolalysenko) wants to merge 4 commits into
Conversation
Assisted-by: Claude Code:claude-opus-5-5
The hosted npm run already reads replace-registry-host from every npm config layer (env, project, user, global, builtin). Read omit-lockfile-registry-resolved the same way, through one shared effective-setting lookup instead of a second copy, and parse its value as npm's ini + nopt Boolean reading does (a bare key, `yes` or `False` are true; `false`, `null` and numeric zero are not). Assisted-by: Claude Code:claude-opus-5-5
With omit-lockfile-registry-resolved=true, the next npm install (even a no-op) drops the hosted `resolved` URL but keeps the patched integrity, so every cold-cache install fails EINTEGRITY and vex loses the patch. The hosted scan said nothing and exited 0. It now warns redirect_npm_omit_lockfile_registry_resolved, naming the config layer that sets it and the remedies (set it to false in the project .npmrc, unset the env var, or use vendored mode). Documented in CLI_CONTRACT.md, docs/ecosystems.md and the npm test matrix. Fixes #1871 Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
Code review, checked against npm 10.9.4: npm reads a blank
omit-lockfile-registry-resolved= as true and a literal `undefined` as
false, because it checks those keywords on the written value before
expanding ${VAR}. The scan read them the other way round, so a blank
value got no warning and `undefined` got a false one.
Also share the where-is-it-set remedy text between the
replace-registry-host and omit-lockfile-registry-resolved warnings,
replace the full JS number parser with a numeric-zero check, and
restore the #1233 test comment the new test had split.
Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 161b4e4. Configure here.
|
Ready for review at
Slack announcement not sent this run (the Slack send tool was unavailable); a later run will retry. Generated by Claude Code |
Final review brief:
|
LLM Description written by Claude Code:claude-opus-5-5
Fixes #1871
Summary
A hosted npm scan now warns
redirect_npm_omit_lockfile_registry_resolvedwhen npm's effective
omit-lockfile-registry-resolvedis true. Beforethis change the scan said nothing and exited 0. The first later
npm install(even a no-op) then dropped the hostedresolvedURL butkept the patched
integrity, so cold-cache installs failed EINTEGRITYand
vexstopped finding the patch.Root cause
The hosted run already reads
replace-registry-hostfrom every npmconfig layer (#812) to warn when npm will undo its pins, but it never
read
omit-lockfile-registry-resolved, which undoes them on the nextlock save in the same way.
Changes
patch/redirect/npmrc.rs:OuterAllowRemotealso resolvesomit-lockfile-registry-resolvedfrom the env / user / global /builtin layers. The env > project > outer lookup now goes through one
private
effective_setting.effective_replace_registry_hostkeepsits signature and uses it too.
npm_config_bool: reads the value the way npm does(
@npmcli/configparseField, then nopt's Boolean check; measured onnpm 10.9.4 through
c.flat). A bare key, a blank value,yesandFalseare true.false/null/undefinedas written are false,and so is a numeric zero after
${VAR}expansion.hosted/engine.rs+hosted/guidance.rs: the new warning namesthe layer that sets the key (env var, project
.npmrc, or a configpath) and the remedies: set it to
falsein the project.npmrc,unset the env var, or use vendored mode. It also says a hosted re-run
re-pins a stripped lock. Same trigger as the
replace-registry-hostwarning, so an "already hosted" re-run warns too. Exit status is
unchanged, and nothing is written to the user's config.
CLI_CONTRACT.md(contract paragraph + warning-code row),docs/ecosystems.md,docs/testing/npm-compatibility.md.npm/,pypi/,gem/) only dispatch to the binary andname no warning codes, so they need no change.
Code review (
/code-review high)Fixed in 161b4e4:
undefinedas true. npm 10.9.4reads them the other way round. Checked with
@npmcli/config.${VAR}value in .npmrc: npm expands it toalways, so every npm ci fails E404, while the hosted scan reports success with no warning #1233 test's doc comment.use one
npm_setting_remedyhelper (replace-registry-hostwordingunchanged).
Number()parser was more than needed; it is now anumeric-zero check.
Not fixed, with reasons:
0spelling hides atrueone. This only happens if bothNPM_CONFIG_…andnpm_config_…are set to different values, whichis far-fetched. The tie-break is shared with every other key
npm_configreads. Changing it to a predicate would touch theallow-remote / allow-file paths outside this fix.
OuterAllowRemotekeeps collecting one field per npm key; make it ageneral key table. That is a design refactor across the
allow-remote, replace-registry-host and allow-file paths, so it is
out of scope for this bug fix. Worth an arch-audit issue if wanted.
Test evidence
vendorsuite:redirect_npm_allow_remote::omit_lockfile_registry_resolved_is_warned(project file on first run + re-run, human stderr, bare key /1/ blank /false/null/undefined/0/ section-scoped, user config, projectfalseover usertrue, env over project)run 0: no redirect_npm_omit_lockfile_registry_resolved), passes with itnpmrc::tests::omit_lockfile_registry_resolved_layers,npmrc::tests::npm_config_bool_matches_npmLocal runs:
cargo fmt --all -- --check: okcargo clippy --workspace --all-features -- -D warnings: okcargo test -p socket-patch-cli --all-features --test vendor -- redirect_npm_allow_remote: 12 passedcargo test --workspace --all-features --no-fail-fast: 15,334 passed, 11 failed. The 11 fail only because of this sandbox and none touch npm config: 9 tests use chmod to force write failures, and they can't fail as root (in_process_redirectx3,repairx2,copy_tree/vlt_heal/pypi_poetry/pypi_requirementsunit tests). The other 2 aree2e_bun_lockbtests that need https://patches-api.socket.dev, which the sandbox proxy blocks, plus the locally installed bun. CI is the check for these.https://claude.ai/code/session_011f9aeNu3D6QeUEGR4pgeCN
Note
Medium Risk
Adds npm hosted-mode advisory logic and Boolean config parsing; behavior is warn-only (no config writes or exit-code changes) but affects operator guidance for lock integrity.
Overview
Hosted npm scans now emit
redirect_npm_omit_lockfile_registry_resolvedwhen npm’s effectiveomit-lockfile-registry-resolvedis true—the same trigger as the existingreplace-registry-hostadvisory, including idempotent “already hosted” re-runs. Previously the run stayed silent while the nextnpm installcould drop hostedresolvedURLs and leave patchedintegrity, causing EINTEGRITY and breakingvex.Resolution follows npm’s config layers (env → project
.npmrc→ user/global/builtin) via sharedeffective_setting, withnpm_config_boolmatching npm’s Boolean parsing. The CLI never rewrites that setting; warnings name the source layer and point toomit-lockfile-registry-resolved=false, unsetting the env var, or vendored mode. Warning copy forreplace-registry-hostis refactored through sharednpm_setting_spelling/npm_setting_remedyhelpers. Docs and integration/unit tests cover the contract and layer precedence.Reviewed by Cursor Bugbot for commit 161b4e4. Configure here.
Generated by Claude Code