404 fetching private NPM package despite setting auth token

Our app requires a private package to build which we publish to NPM. (With expo-cli this wasn’t an issue because the packages were resolved locally and each dev has their local machine configured with access.)

The EAS Build docs for this scenario just say:

  • Configure your project in a way that relies on the NPM_TOKEN env variable to authenticate with private repositories.
  • Add NPM_TOKEN to your account or project’s secrets. See the secret environment variables docs to learn how to do this.

I’ve added the NPM_TOKEN as a secret on our project.

I’ve done what works for our GitLab CI machines, which is using yarn config set, running in the pre-install hook, but adding this to package.json under the scripts section:

"eas-build-pre-install": "yarn config set '//registry.yarnpkg.com/:_authToken' $NPM_TOKEN

I know the secret is being resolved correctly because under “Pre-install hook” when the build runs, I see

$ yarn config set '//registry.yarnpkg.com/:_authToken' $NPM_TOKEN
success Set "//registry.yarnpkg.com/:_authToken" to "<correct token here>".

I’ve also tried:

  • Echoing the right string to .yarnrc
  • Using npm config set instead of yarn config set
  • Trying the --use-yarnrc flag on yarn config

But no matter what I try, when the “Install dependencies” step of the build runs, it gives me

[stderr] error An unexpected error occurred: "https://registry.yarnpkg.com/@growers/<our package>/-/<package-version>.tgz: Request failed \"404 Not Found\"".

The URL it’s using is the URL specified in yarn.lock. I don’t understand why it’s not working.

Has anyone gotten EAS Build working to fetch a private package from NPM?

The URL it’s using is the URL specified in yarn.lock. I don’t understand why it’s not working.

i’m not personally familiar with using private npm packages with yarn, is this unexpected behavior for you? this is what yarn v1 does and it doesn’t provide a way to override it. because of this, we have some instructions for how to use our npm cache with yarn v1 that you may find useful if the url in the yarn lockfile is the issue

Yes, it is unexpected. This configuration works on our dev machines and our Gitlab CI builders. Why should it not work on EAS machines?

So we have to rewrite our yarn.lock file because your builders can’t proxy the request out to the package repository? I understand bandwidth costs money, but we’re on the paid plan. Let us pay what it takes to just fetch the package, as specified, from the repo.

that is not what i am saying at all. i am saying that if you want yarn to use the proxy, you have to set this up manually because of how yarn v1 will just use the url in the lockfile and that can’t be overridden. so the solution to make it use the proxy, if you want it to, is to substitute the url in the lockfile. my suggestion, without knowing much about this specific problem, is that perhaps if the url used for fetching your package is unexpected that this may be a related problem.

it is not clear to me why this is not working in the context of our builders when the same thing would work on your local machine. are you possibly using a different version of yarn?

these seem to be a related issues on the yarn repository:

https://github.com/yarnpkg/yarn/issues/4157
https://github.com/yarnpkg/yarn/issues/2508

and this comment: https://github.com/yarnpkg/yarn/issues/3330#issuecomment-470490312

so maybe you are using yarn v2 locally and on gitlab. if so, you should use it on eas build also. you can set the version on a build profile: Configuring EAS Build with eas.json - Expo Documentation

my suggestion, without knowing much about this specific problem, is that perhaps if the url used for fetching your package is unexpected that this may be a related problem.

I added a step to the pre-install hook to try doing a curl -I on the URL to make sure it is accessible from the build machine, and it is. Which makes it seem like for whatever reason the yarn config set value set in the pre-install step is being ignored. Link to build: Build Details — 67e69bd5-836c-45a0-96ac-92ffe7ad52d8 — growers-rally — Expo

so maybe you are using yarn v2 locally and on gitlab

Yarn v1 all around. According to the second line of the “Install Dependencies” step, it’s using the same yarn version I’m using locally: 1.22.10. I added it to eas.json and ran again, same result.

you could try also doing yarn config set always-auth true
i have seen this mentioned in issues on the yarn repository where developers have encountered the same problem as you

No change. Same result. Seems like the settings being specified by yarn config set are not being obeyed. Build Details — 8d33489b-ade6-4284-88a4-1eb725d10f28 — growers-rally — Expo

do you know where the documentation for using private npm packages with yarn classic lives? i have been unable to find it on the yarn classic docs

i tried setting this up myself and i found out that in my experience the read-only token type suggested by npm actually didn’t work for reading private packages.

i tested this by creating .npmrc within my project directory, setting NPM_TOKEN, and then signing out of npm. i then deleted node_modules and ran yarn. got a 404 error. swapped the NPM_TOKEN with an “automation” token and it worked. you could possibly try the same thing on your end.

here’s a link to a repository that works well for me: GitHub - brentvatne/forums-57274

steps to get it to work:

  1. add NPM_TOKEN secret created with “automation” privileges (read-only did not work for me)
  2. create .npmrc in your project directory (or do it in the pre-install script) and set the npm registry (see this commit)

i think we should improve our documentation on this, i’ll take care of that. i do wonder if maybe npm has introduced a regression recently around read-only tokens and private packages, however.

1 Like

Not that it really matters now, but just to clarify :slight_smile::
@growersbenb said “The URL it’s using is the URL specified in yarn.lock.” and @notbrent was asking whether that was unexpected. Given the rest of the conversation I do not think it was unexpected.

I have validated that the token I’m supplying to the EAS Build allows access to this package, both on my local machine and in the pre-install hook via curl -I. The token is valid.

For whatever reason, yarn is not using it.

I added a yarn config list to the end of the pre-install script, which shows the settings I would expect to be there: Build Details — 54073242-4ac8-4daa-9613-44f0b62fc059 — growers-rally — Expo .

Is it possible that the start of the install step is overwriting .yarnrc, or that the .yarnrc.yml described here conflicts with my .yarnrc settings and the two are not being merged? Is there a way for yarn config list to be run at the beginning of the install step so we can inspect what the settings are just before yarn install runs?

Edit: just tested this config locally. On my machine, running yarn 1.22.10, if there is both ~/.yarnrc and ~/.yarnrc.yml, the .yml file is ignored and only ~/.yarnrc appears to be being read.

I’ve got this working, somewhat hackily, by doing this in the pre-install step:

npm config set '//registry.yarnpkg.com/:_authToken' $NPM_TOKEN
yarn install

yarn config set does not work, but npm config set does. Couldn’t tell you why.

For some reason, letting the install happen in the actual install step doesn’t work, but calling it from within the “pre-install” hook does. Build Details — af779edf-499a-4c1a-81e6-7f562928a917 — growers-rally — Expo

Now onto the next error…

This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.