npm Scoped Registry 404 - Fix Missing @scope:registry Mapping in CI
A scoped package resolves to whatever registry its scope is mapped to. With no @scope:registry= line, npm asks the default public registry - which legitimately 404s on a private scoped package.
What this error means
Installing @yourscope/pkg 404s while public packages install fine. The scope is not mapped to your private registry, so npm queried the public one, which has never heard of the package.
npm error code E404
npm error 404 Not Found - GET https://registry.npmjs.org/@yourscope%2fpkg
npm error 404 '@yourscope/pkg@^1.0.0' is not in this registry.
# no "@yourscope:registry=" line, so npm used the public defaultCommon causes
The scope is not mapped to its registry
Without @yourscope:registry=https://your-registry/, npm sends scoped requests to the default registry, producing a genuine 404 for a private package.
The scope maps to the wrong host
A stale or copy-pasted mapping points the scope at a registry that does not host the package, again yielding a 404.
How to fix it
Map the scope to the correct registry
Add a per-scope registry line (and the matching auth) in the CI .npmrc.
cat > .npmrc <<'EOF'
@yourscope:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}
EOF
NODE_AUTH_TOKEN="$REGISTRY_TOKEN" npm ciVerify the mapping and host
- Confirm the scope name in the mapping matches the package scope exactly.
- Check the registry host actually hosts that scope.
- If it 404s only in CI, suspect a missing mapping/token, not a missing package.
How to prevent it
- Map every private scope to its registry in .npmrc.
- Keep scope→registry mappings in sync across local and CI.
- Provide credentials for each mapped private host.