Skip to content

fix(config): normalize registry URL trailing slash in nerfDart to prevent scope key mismatch#9555

Open
heunghingwan wants to merge 1 commit into
npm:latestfrom
heunghingwan:latest
Open

fix(config): normalize registry URL trailing slash in nerfDart to prevent scope key mismatch#9555
heunghingwan wants to merge 1 commit into
npm:latestfrom
heunghingwan:latest

Conversation

@heunghingwan

Copy link
Copy Markdown

Problem

nerfDart() in @npmcli/config uses new URL('.', url) to compute a scope key (e.g. //host/path/) for credential lookup. URL resolution treats a path without a trailing slash as a file, so the last segment is discarded:

Input nerfDart output
https://host/npm/ //host/npm/
https://host/npm //host/ (segment lost)

getCredentialsByURI only checks this single computed key with no backtracking. This means a registry URL with a path component (e.g. https://host/npm) produces the scope key //host/, which collapses auth to the entire host and can collide with other registries on the same host at different paths.

Meanwhile, npm-registry-fetch (the HTTP layer) uses its own path-backtracking logic and handles this correctly.

Fix

Introduce nerfDartURI() — a wrapper around nerfDart() that ensures the URL pathname always ends with / before computing the scope key. Since all callers (getCredentialsByURI, setCredentialsByURI, clearCredentialsByURI, and the auth validation in validate) receive registry base URLs (not package/API URLs), this normalization is safe.

Updated all 4 nerfDart() call sites in workspaces/config/lib/index.js to use nerfDartURI().

Before vs After

nerfDart("https://host/npm")  →  //host/      (wrong — loses path)
nerfDartURI("https://host/npm") → //host/npm/  (correct)

Both https://host/npm/ and https://host/npm now produce the same key //host/npm/.

Impact

  • Existing .npmrc files with auth stored at an incorrect collapsed scope (//host/:_authToken instead of //host/path/:_authToken) will need npm login to regenerate the key at the correct scope.
  • This is a bug fix — the old behavior was overly broad in its scope matching.

@heunghingwan heunghingwan requested review from a team as code owners June 14, 2026 17:51
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