Npm install from gitlab package registry not working

I’ve published an npm package to my private group. This is the link for npm: https://gitlab.com/api/v4/packages/npm/@coeng2020%2Fservice-fetcher

using npm i @coeng2020/service-fetcher i get a 404 not found message.

But when I paste the link in a broswer, I get a 304 with all the required info for npm.

Is there something Im missing from my setup?

i’ve also ran this command already in my repo: echo @coeng2020:registry=https://gitlab.com/api/v4/packages/npm/ >> .npmrc

Please help

3 Likes

For private projects make sure you’ve also setup authentication to the registry for it to be able to resolve your project and package: https://docs.gitlab.com/ee/user/packages/npm_registry/#authenticate-with-a-personal-access-token-or-deploy-token

I have published the npm package to gitlab.com without a problem.

In another private project, I want to consume this npm package. It works locally after setting up the .npmrc with my personal access token accordingly and when executing npm install @my-org/project_a.

However, it fails when the gitlab pipeline wants to install it with the following messages:

npm ERR! code E404
62npm ERR! 404 Not Found - GET https://gitlab.com/api/v4/projects/<id_of_project_a>/packages/npm/@my-org/project_a/-/@my-org/project_a-0.0.7.tgz
63npm ERR! 404 
64npm ERR! 404  '@my-org/project_a@https://gitlab.com/api/v4/projects/<id_of_project_a>/packages/npm/@my-org/project_a/-/@my-org/project_a-0.0.7.tgz' is not in the npm registry.

I have set up the .npmrc in the gitlab-ci.yml as well and I have tried out several auth keys, including my personal access token and the $CI_JOB_TOKEN . I have also cleared the gitlab runner cache several times.

Accessing the url https://gitlab.com/api/v4/projects/<id_of_project_a>/packages/npm/@my-org/project_a/-/@my-org/project_a-0.0.7.tgz also works via the browser.

Do you have an idea why it works locally and fails on gitlab ci cd even with the same access tokens and .npmrc ?

How can I debug this?

1 Like

Hello
I got same error with a private package. How did You manage to solve It?
Thanks so much

Hi Pavel,

I managed to get it to work with a separate personal access token. Here is what i did:

  • Create a personal access token from Gitlab with the permissions read_api and read_registry.

  • Expose this personal access token in the gitlab ci pipeline through a variable

  • Ensure the .npmrc has the following content:

# Set URL for your scoped packages, e.g. package with name `@my-org/my-package` will use this URL for download.
"@your_org_scope:registry"="https://gitlab.com/api/v4/packages/npm/"

# Add the token for the scoped packages URL. This will allow you to download.
# Make sure you replace ${GITLAB_AUTH_TOKEN} with the personal access token copied earlier or create a local environment variable (this is recommended) named GITLAB_AUTH_TOKEN with the token copied earlier as the value.
"//gitlab.com/api/v4/packages/npm/:_authToken"="${GITLAB_AUTH_TOKEN}"

# Add token for uploading to the registry.
# NOTE: Currently, the project id is XXXXXX. If this changes, you will need to adjust this accordingly.
"//gitlab.com/api/v4/projects/<<project_id>>/packages/npm/:_authToken"="${GITLAB_AUTH_TOKEN}"

And then npm install should work in the gitlab as well.

I was not able to get it working with the CI_TOKEN

4 Likes

Awesome. That did the trick!
Thanks so much for your help

Another issue I have faced - if you just copy the provided command ech @mynamespace:registry=htttps:....... >> .npmrc, it may look wrong for npm. Check it with command - npm config ls, and see how it looks there. For me, before each letter in the URL, there was a \u0000 character inserted - @mynamespace:registry = "\u0000h\u0000t\u0000t\u0000p\u0000s\u0000:\u0000/\u0000/\u0000g\u0000i\u0000t\u0000l\u0000a\u0000b\u0000....... Manually pasting that part into the .nmprc file worked.

Thanks, this also worked for me

Thanks! In my case, group access tokens with role “Reporter” and scope “read_api” also managed to get it to work: Group access tokens | GitLab

npm cannot download a package on a self-hosted GitLab instance, although there is a project local .npmrc. But it works when the package is hosted on gitlab.com

Error message: npm ERR! 404 Not Found - GET https://registry.npmjs.org/@myscope/mypackage - Not found

npm i seems to read the project local .npmrc:

grep npmrc /home/myuser/.npm/_logs/2023-03-14T10_54_45_824Z-debug-0.log
5 timing config:load:file:/home/myuser/.nvm/versions/node/v18.15.0/lib/node_modules/npm/npmrc Completed in 0ms
9 timing config:load:file:/home/myuser/projects/pe/mypackage_test/.npmrc Completed in 2ms
11 timing config:load:file:/home/myuser/.npmrc Completed in 2ms
13 timing config:load:file:/home/myuser/.nvm/versions/node/v18.15.0/etc/npmrc Completed in 0ms

strace shows no access to .npmrc files or to the host of the self hosted GitLab instance.

Test exercised with a personal access token with corresponding permissions.

Any chance you figured this out? I have run into the same issue.

Using the project level URL works, however when I try to use the instance level URL I get forwarded to NPM which results in a 404.

Pasting the URL into my browser shows the same thing. Project level URL returns valid JSON, instance level URL forwards me to NPM & I get a 404.

It works now for instance wide npm packages.

The following steps worked for me:

Install task from https://taskfile.dev

create some directory and go into this directory.

create a file Taskfile.yml with this content:

# https://taskfile.dev

version: '3'

vars:
  GREETING: npm-demo

tasks:
  test:
    cmds:
      - npm config ls
    preconditions:
      - test -f .npmrc

  npmrc-generate:
    vars:
      GENERATED_FILE_NAME: .npmrc
      CONTENT: |
        @${GITLAB_NPM_SCOPE}:registry=https://${GITLAB_NPM_SERVER}/api/v4/projects/${GITLAB_PROJECT_ID}/packages/npm/
        //${GITLAB_NPM_SERVER}/api/v4/projects/${GITLAB_PROJECT_ID}/packages/npm/:_authToken="${NPM_TOKEN}"
    cmds:
      - |
        cat << EOF > "{{.GENERATED_FILE_NAME}}"
        {{range $i, $line := .CONTENT | splitLines -}}
        {{$line}}
        {{end}}EOF
    status:
      - test -f "{{.GENERATED_FILE_NAME}}"

run npm init -f -y

create a file .envrc with this content:

export NPM_TOKEN=<your-token>
export GITLAB_NPM_SERVER=<your-gitlab-server>
export GITLAB_PROJECT_ID=<your-gitlab-project-id>
export GITLAB_NPM_SCOPE=<your-npm-scope>

load .envrc either with direnv allow . or according to your currently active shell, for example with . ./.envrc

run task npmrc-generate

run task test and verify that there are two lines, one beginning with @<your-npm-scope>/... and the second line beginning with //<your-gitlab-server

install your scoped package with: npm i @scope/somepackage, generalized: npm i @<your-npm-scope>/<your-npm-package>

small syntactical problems in the .npmrc file cause npm to not find the scoped package.

The command
echo @philrousse:registry=https://gitlab.forge.gouv.qc.ca/api/v4/packages/npm/ >> .npmrc
Generate a file

That file need to be encoded in UTF-8. For me, it was UTF-16.

In VS-Code, just click on the encoding in the bottom right, select UTF-8 and save with this encoding.

It would seem a self-hosted gitlab instance doesn’t read the project file .npmrc
I added the following line in my CI and it finally worked:

  script:
    - npm config set @my.scope:registry https://my.repository.org/npm/
    - npm i

Would love to know why the project .nprmc is not read by the job.

Bro this works like a champ.
I have to register a new forum account just to like your comment and thank you.

Also I want to add that if your project has multiple private repos which has different project_id. You will have to add the token for every single one of them. For example:

always_auth=true
"@your_org_scope:registry"="https://gitlab.com/api/v4/packages/npm/"
"//gitlab.com/api/v4/packages/npm/:_authToken"="${GITLAB_AUTH_TOKEN}"
"//gitlab.com/api/v4/projects/<<project_id_a>>/packages/npm/:_authToken"="${GITLAB_AUTH_TOKEN}"
"//gitlab.com/api/v4/projects/<<project_id_b>>/packages/npm/:_authToken"="${GITLAB_AUTH_TOKEN}"
"//gitlab.com/api/v4/projects/<<project_id_c>>/packages/npm/:_authToken"="${GITLAB_AUTH_TOKEN}"

So, npm will first get your package download URL at: gitlab.com/api/v4/packages/npm/@your_org_scope/your_package. Then it will download the .tgz file from https://gitlab.com/api/v4/projects/project_id_a/packages/npm/@your_org_scope/your_package/-/@your_org_scope/your_package-0.0.1.tgz which will also need the token