🐛 ? NPM Package Registry URL Encoding Issue with Scoped Packages

NPM Package Registry URL Encoding Issue with Scoped Packages

Summary

When using npm to install or update scoped packages from GitLab Package Registry, npm incorrectly encodes the forward slash in scoped package names with dots (e.g., @organization.name/package becomes @organization.name%2fpackage in the URL), resulting in 404 errors.

Environment Details

  • npm version: 10.7.0 / 10.8.2
  • Node.js version: v20.14.0 / v20.19.0
  • Operating system: MacOS / Linux

Steps to Reproduce

  1. Configure .npmrc with GitLab Package Registry

    @organization.name:registry=https://gitlab.com/api/v4/projects/<PROJECT_ID>/packages/npm/ //gitlab.com/api/v4/projects/<PROJECT_ID>/packages/npm/:_authToken=<AUTH_TOKEN>

  2. Try to install or update a scoped package

    npm update @organization.name/package

  3. Observe the error:

    npm ERR! code E404 npm ERR! 404 Not Found - GET https://gitlab.com/api/v4/projects/<PROJECT_ID>/packages/npm/@organization.name%2fpackage - Packages not found npm ERR! 404 npm ERR! 404 '@organization.name/package@~x.y.z' is not in this registry. npm ERR! 404

Expected Behavior

npm should properly construct URLs for GitLab Package Registry without encoding the forward slash in the package scope, or GitLab should accept URLs with encoded slashes (%2f).

Actual Behavior

npm encodes the forward slash in the package name as %2f when making requests to GitLab Package Registry. The GitLab API does not properly handle these encoded URLs, resulting in 404 errors.

Debug Information

When checking the request URLs in the npm log, we can see that npm is sending requests to:

https://gitlab.com/api/v4/projects/<PROJECT_ID>/packages/npm/@organization.name%2fpackage

Instead of the correct URL format:

https://gitlab.com/api/v4/projects/<PROJECT_ID>/packages/npm/@organization.name/package

In a browser, the URL with / works initially but redirects to the encoded URL with %2f.

Workarounds Attempted

  1. Explicitly specifying the registry with --registry flag
  2. Adding different forms of the scope configuration in .npmrc
  3. Clearing npm cache
  4. Using alternate package managers

None of these workarounds successfully resolved the issue.

Impact

This issue prevents teams from using npm to install or update scoped packages from GitLab Package Registry, significantly disrupting development workflows. This is particularly problematic for organizations that use domain-style scopes in their package names (e.g., @organization.name/*).

Possible Solutions

  1. GitLab Package Registry should accept and properly handle URLs with encoded slashes (%2f)
  2. Implement a server-side redirect to handle encoded URLs properly
  3. Document a workaround for npm users if a fix is not immediately possible

Any assistance with this issue would be greatly appreciated, as it's currently blocking our development workflow.

Edited by 山脇 教由樹