Repository navigation
[BUG] --dry-run fails with EALLOWREMOTE on registry tarballs for packages that declare bundleDependencies #9800
Description
Is there an existing issue for this?
- I have searched the existing issues
The closest reports have a different cause: #9796 (registry serving tarballs from a path outside the configured registry prefix) and the closed exemption fixes #9494 / #9548 / #9509. This one happens against the default registry.npmjs.org and only under --dry-run. #9187 is a separate --dry-run bug (side effects / output).
This issue exists in the latest npm version
- I am using the latest npm
This is not just a request to bump a dependency for a CVE
- This is not solely a request to bump a dependency for a CVE
Current Behavior
With npm 12's default allow-remote=none, npm install --dry-run refuses a registry-hosted tarball when the target package — or a package in its graph — declares bundleDependencies:
$ npm i --dry-run npm@11.10.0
npm error code EALLOWREMOTE
npm error Fetching packages of type "remote" have been disabled
npm error Refusing to fetch "https://registry.npmjs.org/npm/-/npm-11.10.0.tgz"The identical command without --dry-run succeeds. The refused URL is a registry.npmjs.org tarball and registry is the default, so the registry-tarball exemption should apply.
| command | result |
|---|---|
npm i --dry-run npm@11.10.0 |
EALLOWREMOTE |
npm i npm@11.10.0 |
added 1 package |
npm i --dry-run @tailwindcss/oxide@4.3.3 |
EALLOWREMOTE |
npm i @tailwindcss/oxide@4.3.3 |
added 2 packages |
npm i --dry-run lodash@4.17.21 (control, no bundleDependencies) |
added 1 package |
@tailwindcss/oxide is the realistic case: it bundles nothing itself, but its optional @tailwindcss/oxide-wasm32-wasi dep declares bundleDependencies — and since that package is cpu: ["wasm32"], a real install skips it entirely, which is presumably why only the dry-run path trips.
Practical impact: npm update --dry-run to preview a bump fails in any project whose tree contains such a package (anything on Tailwind 4, for instance), while the real npm update completes fine. In a monorepo that makes the preview unusable without --allow-remote=all, which is exactly the guard one doesn't want to relax to inspect a change.
Not caused by min-release-age: reproduces with --min-release-age=0 explicitly passed.
Expected Behavior
--dry-run should apply the same registry-tarball allow-remote exemption a real install does. Declaring bundleDependencies shouldn't cause a registry spec to be classified as type remote.
Steps To Reproduce
$ mkdir /tmp/eallowremote && cd /tmp/eallowremote && npm init -y
# both fail with EALLOWREMOTE
$ npm i --dry-run npm@11.10.0
$ npm i --dry-run @tailwindcss/oxide@4.3.3
# both succeed
$ npm i npm@11.10.0
$ npm i @tailwindcss/oxide@4.3.3
# control: no bundleDependencies, dry-run is fine
$ npm i --dry-run lodash@4.17.21Environment
- npm: 12.0.1
- Node.js: 24.18.0
- OS Name: Linux 7.0.11 (x86_64)
- System Model Name: n/a
- npm config:
; user config (registry auth lines omitted)
min-release-age = 7
min-release-age-exclude = ["@fullbeaker/*"]
registry = "https://registry.npmjs.org/"
; relevant npm 12 defaults, not overridden
allow-remote = "none"
allow-git = "none"
Activity
shooley-apco commentedon Jul 28, 2026
Independently reproduced on Windows 11 / npm 12.0.1 / Node v22.23.1, against the default
registry.npmjs.org. I arrived at this from the other direction and can point at the call site.--dry-runisn't the only trigger —--package-lock-onlyis too.reify.jsbuilds its ideal-tree options as:So anything that sets either flag is affected. In a Tailwind 4 monorepo that makes
npm dedupefail outright, not just previews:The failing call site is the ideal-tree "crack open", not the reify extract:
That's
#buildDepStep'scrackOpenbranch, whose own comment explains why it only happens here:node.resolvedis a bare URL, so npa classifies the spec as typeremoteand pacote's gate fires.reify.jsalready handles exactly this hazard for its own extract:The crack-open call site has no equivalent. A code search for
isRegistryResolvedTarballacross this repo returns onlyworkspaces/arborist/lib/arborist/reify.js, so the exemption added in #9348 / #9495 / #9510 / #9550 never reachedbuild-ideal-tree.js— which would explain why this survived those four fixes.One correction to the issue body: the reason a real install is unaffected isn't that it skips the
cpu: ["wasm32"]package — it's the#completegate. A reification reads bundles in place (per the comment above) and never cracks the tarball open, so the platform mismatch is incidental. That also predicts the control case correctly:lodashpasses becausehasBundleis false, not because of anything platform-related.Two smaller notes:
--allow-remote=rootis not a usable middle ground. This extract passes no_isRoot, socanUseseesisRoot: falseand refuses with thenon-rootwording regardless.allis the only value that unblocks it, which sharpens your point about relaxing the guard just to inspect a change.#nodeFromSpecroutes#checkAllowrejections through#failureNodeso optional-dependency semantics apply; thecrackOpenextract isn't wrapped, so a transitive, platform-mismatched optional dep hard-fails the command instead of being dropped.Line numbers are from the published 12.0.1 bundle and may be offset slightly from
main.chgeo commentedon Aug 6, 2026
Can this be fixed soon? Two patch candidates are available.
coderbyheart commentedon Aug 17, 2026
Thanks for the detailed report. I have encountered the same issue for projects that depend on
@aws-cdk/cloud-assembly-schema.chore: work around npm 12 EALLOWREMOTE bug in Renovate lockfile updates
chore: npm を 12 に固定し、.npmrc を org 共通の基準に揃える
ci(cli-publish-verify): add --allow-remote=all to npm install steps
ci(cli-publish-verify): set allow-remote via .npmrc (CLI flag is igno…
ci(cli-publish-verify): pin Node 20 to dodge npm 11 install --dry-run…
ci(cli-publish-verify): revert experimental npm 11.19 workarounds
TiBata commentedon Sep 17, 2026
Adding test results for the two candidate PRs, since neither has been reviewed yet.
As noted above,
--package-lock-onlyis also a trigger. That is the command Renovate runs for lock file maintenance, so Renovate-managed projects depending on Tailwind CSS 4 (@tailwindcss/oxide) get an "Artifact update problem" as soon as Renovate resolves npm 12.Minimal repro (Node 24.21.0):
Both PRs run from source against this repro:
install --package-lock-only(no lockfile)install --dry-runinstallOn a real project (Astro + Tailwind 4, 437 lockfile entries), the lockfile regenerated from scratch by either PR is identical to npm 11.19.0's: same entries, versions and integrity. Either PR would unblock these users. The current workarounds are pinning npm to 11 via
engines.npm/packageManager, or settingallow-remote=all, which gives up the new default.MikeMcC399 commentedon Sep 17, 2026
@TiBata
Thanks for tying this in to Renovate! We're also seeing this in a public repo - see cypress-io/github-action#1900 (comment)
I came up with the same conclusion as you regarding the workarounds and I'm going for the
allow-remote=allright now because it sets the default the same as npm <12.10 remaining items
fix(renovate): let npm 12 regenerate lockfiles with bundled dependenc…
chore(renovate): regenerate package-lock.json with npm 11
fix(renovate): hold Renovate's npm below 12 to match CI (#273)
ci: fail when npm/cli#9800 is fixed so workaround can be removed
ci: fix npm/cli#9800 probe so it reproduces the real failure
ci: surface npm/cli#9800 probe results on every PR without blocking
ci: make npm/cli#9800 probe failures block PRs
ci: report npm/cli#9800 probe only through the check status
chore: pin renovate's npm to 11 for lockfile updates
npm: Let npm 12 fetch registry tarballs for the lockfile
chore(renovate): pin npm to 11 for lockfile updates
pin npm to fix renovate failures (see npm/cli#9800)
chore(deps): update non-major
Work around npm 12 EALLOWREMOTE in Renovate lockfile updates (#726)
chore(deps): update non-major (#725)