cli icon indicating copy to clipboard operation
cli copied to clipboard

[BUG] Incorrect resolution for missing resolved-entries with non-empty registry path

Open next-mad-hatter opened this issue 1 month ago • 0 comments

Is there an existing issue for this?

  • [x] I have searched the existing issues

This issue exists in the latest npm version

  • [x] I am using the latest npm

Current Behavior

In our ci setup we have an internal registry.npmjs.org mirror which is available via https address with a base prefix, i.e. our local .npmrc files usually feature

registry=https://ci.host/repository/npm/

Now, when running npm i -ddd with no lock file present, everything works as expected, the logs show requests like

npm http fetch GET 200 https://ci.host/repository/npm/qs

and a package-lock.json files is created and populated with entries like

"resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz"

However, when a resolved-entry is missing in the package-lock.json file (which can happen due to e.g. https://github.com/npm/cli/issues/4263, which I can reproduce locally with npm 11.6), the repository path is not being calculated correctly and npm ci fails with

npm error 404 Not Found - GET https://ci.host/ansi-styles/-/ansi-styles-4.3.0.tgz

I'm not sure about the exact source of this behaviour -- all I can say at this moment is that I see different values arriving in pacote/lib/remote.js at the line

this.resolved = new URL(resolvedURL.pathname, this.registry).href

When running npm i without the lock file, the pathname contains extracted registry address prefix, while with package-lock.json present, it does not.

Expected Behavior

Missing entries should get resolved to correct registry address, i.e. https://ci.host/repository/npm/ansi-styles/-/ansi-styles-4.3.0.tgz in place of https://ci.host/ansi-styles/-/ansi-styles-4.3.0.tgz above.

Steps To Reproduce

In an empty dir, create simple package file

cat > package.json
{
  "dependencies": {
    "yn": "^5.1.0",
    "zwitch": "^2.0.4"
  }
}
^D

then run

# install packages as usual
npm i

# trigger vanishing resolved-entry via #4263
# (alternatively, simply remove a resolved entry from the lock file)
rm -r node_modules/yn package-lock.json
npm i

# the error is also present if this is done as first step;
# repository needs to be available under the path for wrong address to show
echo registry=https://ci.host/repository/npm/ > .npmrc

# witness incorrect resolution
rm -r node_modules
npm ci --ddd
# throws, using incorrect path
# ...
# npm silly audit bulk request { yn: [ '5.1.0' ], zwitch: [ '2.0.4' ] }
# npm silly packumentCache corgi:https://ci.host/repository/npm/zwitch cache-miss
# npm http cache yn@https://ci.host/repository/npm/yn/-/yn-5.1.0.tgz 1ms (cache hit)
# npm http fetch GET 200 https://ci.host/repository/npm/zwitch 323ms (cache revalidated)
# npm silly packumentCache corgi:https://ci.host/repository/npm/zwitch set size:15580 disposed:false
# npm http fetch GET 404 https://ci.host/zwitch/-/zwitch-2.0.4.tgz 57ms (cache skip)
# npm verbose stack HttpErrorGeneral: 404 Not Found - GET https://ci.host/zwitch/-/zwitch-2.0.4.tgz
# ...
# npm error 404 Not Found - GET https://ci.host/zwitch/-/zwitch-2.0.4.tgz
# ...

Environment

  • npm: 11.6.1, 11.6.2, 10.9.4
  • Node.js: 24.11.0
  • OS Name: Linux
  • npm config:
; "project" config from /home/username/npm-test/.npmrc

fund = false
registry = "https://ci.host/repository/npm/"

; "cli" config from command line options

long = true

next-mad-hatter avatar Nov 03 '25 14:11 next-mad-hatter