129

I am trying to build a react app, but when I execute the command npm -i it gives me the following error:

Error: Failed to replace env in config: ${NPM_TOKEN}
    at /usr/local/lib/node_modules/npm/lib/config/core.js:415:13
    at String.replace (<anonymous>)
    at envReplace (/usr/local/lib/node_modules/npm/lib/config/core.js:411:12)
    at parseField (/usr/local/lib/node_modules/npm/lib/config/core.js:389:7)
    at /usr/local/lib/node_modules/npm/lib/config/core.js:330:24
    at Array.forEach (<anonymous>)
    at Conf.add (/usr/local/lib/node_modules/npm/lib/config/core.js:328:23)
    at ConfigChain.addString (/usr/local/lib/node_modules/npm/node_modules/config-chain/index.js:244:8)
    at Conf.<anonymous> (/usr/local/lib/node_modules/npm/lib/config/core.js:316:10)
    at /usr/local/lib/node_modules/npm/node_modules/graceful-fs/graceful-fs.js:78:16
/usr/local/lib/node_modules/npm/lib/npm.js:61
      throw new Error('npm.load() required')
      ^

Error: npm.load() required
    at Object.get (/usr/local/lib/node_modules/npm/lib/npm.js:61:13)
    at process.errorHandler (/usr/local/lib/node_modules/npm/lib/utils/error-handler.js:205:18)
    at process.emit (events.js:182:13)
    at process._fatalException (internal/bootstrap/node.js:448:27)

I am using MacOS High Sierra. I tried to set the NPM_TOKEN as an environment variable with following command:

set -x NPM_TOKEN = xyz

but it doesn't work. What is the problem?

funtik
  • 1,688
  • 3
  • 11
  • 27
  • 2
    Possible duplicate of [Failed to replace env in config using Bash & NPM](https://stackoverflow.com/questions/35483721/failed-to-replace-env-in-config-using-bash-npm) – Hemadri Dasari Aug 25 '18 at 09:31
  • Did you find a solution to this problem? I've followed all the instructions in all the linked questions etc and I got nothin – JSilv Nov 02 '18 at 16:00
  • @JSilv see my answer: https://stackoverflow.com/a/55610638/5922757 – Jezor Apr 10 '19 at 10:47
  • Here you can find my solution https://stackoverflow.com/a/67648863/14178236 – Aman Gupta May 22 '21 at 11:25

20 Answers20

114

Actually proper solution

Update your CI deployment configuration:

npm config set '//registry.npmjs.org/:_authToken' "${NPM_TOKEN}"
npm publish

Remove this line from the .npmrc file:

//registry.npmjs.org/:_authToken=${NPM_TOKEN}

Example build config

You can see this solution used in practice in one of my GitHub repositories: https://github.com/Jezorko/lambda-simulator/blob/5882a5d738060c027b830bcc2d58824c5d27942b/.github/workflows/deploy.yml#L26-L27

The encrypted environment variable is an NPM token.

Why the other "solutions" are mere workarounds

I've seen answers here and under this question that recommend simply removing the variable setting line or .npmrc file entirely.

Thing is, the .npmrc file might not be ignored by your VCS system and modifying it might lead to accidental pushes to your project's repository. Additionally, the file may contain other important settings.

The problem here is that .npmrc does not allow defaults when setting up environment variables. For example, if the following syntax was allowed, the issue would be non-existent:

//registry.npmjs.org/:_authToken=${NPM_TOKEN:-undefined}

Jezor
  • 3,253
  • 2
  • 19
  • 43
  • 4
    Executing `npm config set '//registry.npmjs.org/:_authToken' "${NPM_TOKEN}"` threw the exact same error from title for me. Resolved only using the first workaround in the accepted answer. – alelom Aug 16 '19 at 09:39
  • 7
    This approach would leak "${NPM_TOKEN}" to any user on a machine able to list processes and their arguments, eg. with `ps`, `pgrep` etc. – Wade Jensen Aug 20 '19 at 02:18
  • 1
    added to Jenkinsfile and works like a charm! This is exactly what I was looking for! Cheers! – Kamil Janowski Sep 02 '19 at 05:58
  • 1
    @WadeJensen If you are afraid of passing sensitive information as command parameters, perhaps your CI/CD environment is not secure enough. What you described would require constant monitoring of processes and their arguments, `npm config set` executes rather quickly for a human to catch the exact moment it runs. This implies you have a user with malicious intentions with access to your machine… Anyhow, you can use some other command to write token to npm config file (one that doesn't use command line args). – Jezor Sep 09 '19 at 07:29
  • @alexlomba87 what are the contents of your `.npmrc` file? Perhaps you're setting literally `${NPM_TOKEN}` instead of an environment variable? – Jezor Sep 09 '19 at 07:30
  • 4
    @Jezor a lot of developers work on multi-tenant internal systems which are behind corporate firewalls, but are loosely secured from internal users. You want your security model to be "crunchy everywhere", not "hard shell outside, soft-gooey inside". – Wade Jensen Sep 10 '19 at 05:38
  • 1
    @WadeJensen I think we are agreeing, then! Only few admin users should have access to CI/CD internals (SSH / admin), devs should only see pipeline results. Still, you can commit a test that just reads `.npmrc` and fetches the token - there's a certain point where adding more restrictions doesn't increase security anymore. – Jezor Sep 10 '19 at 07:37
  • @funtik since this answer has received much support, could you please consider marking it as the accepted answer? The current accepted answer is quite misleading. – Jezor Jul 18 '21 at 09:47
  • 1
    This answer should go to the top. – oyalhi Aug 20 '21 at 23:39
  • Good stuff, worked over here! Nice to not have to use that file. – Jannik Oct 14 '21 at 16:28
  • this worked for me but every time I restart the computer I need to do it again. Any ideas why? – kilinkis Nov 04 '21 at 11:15
  • @kilinkis difficult to say without taking a look at your deployment script. Are you deploying from your machine instead of a CI server? – Jezor Nov 11 '21 at 11:28
  • @Jezor is not a CI context, is just my machine and I'm trying to run stuff like `yarn storybook`, then get the error in the question, and by doing this proposed solution it works after, until the next restart. Now I export the key in my zhsrc and removed that line from .npmrc. We'll see how that works next time I restart. – kilinkis Nov 11 '21 at 21:57
  • 1
    @kilinkis locally you should keep the token in your user `.npmrc` file, `~/.npmrc` (: – Jezor Feb 09 '23 at 12:29
108

First Possible Solution:

Simple Solution: rm -f ./.npmrc (Deleting a .npmrc file)

Second Possible Solution:

However if you don't want to delete the file, you can simply remove this line of code in the .npmrc file.

Line of Code: //registry.npmjs.org/:_authToken=${NPM_TOKEN} (Remove this code)

Third Possible Solution

Worst case scenario:

  • nano ~/.bash_aliases or nano ~/.bash_profile
  • add export NPM_TOKEN="XXXXX-XXXXX-XXXXX-XXXXX"
  • CTRL + X to exit
  • Y to save
accimeesterlin
  • 4,528
  • 2
  • 25
  • 18
  • 39
    This is not a solution, but a workaround. A proper solution would be to remove this line and update your CI deployment configuration like `npm config set '//registry.npmjs.org/:_authToken' "${NPM_TOKEN}" && npm publish`. – Jezor Apr 10 '19 at 10:36
  • 7
    I am missing the why of this solution, would have been nice to have it. – Andrea.cabral Dec 02 '19 at 13:10
  • 14
    If you remove this line from the file how then do you gain access to the private repo? – Kevin Genus May 22 '20 at 20:26
  • Have to reiterate that the above is not a solution and the *worst case scenario* as it is described, is a viable solution in some circumstances. – johnny Feb 11 '21 at 23:01
  • You might need to set your NPM_TOKEN in your environment (e.g. .zprofile, .bashrc) – Professor Todd Sep 09 '21 at 16:43
  • 5
    "Yeah, just delete the file or the line that causes problems" Great solution! /s –  Feb 07 '22 at 07:45
53

I have an easy solution to this issue. After you set your NPM_TOKEN globally into your environment then replace

//registry.npmjs.org/:_authToken=${NPM_TOKEN}

with

//registry.npmjs.org/:_authToken=$NPM_TOKEN

It's worked well for me on macOS Catalina.

Striped
  • 2,544
  • 3
  • 25
  • 31
Rohman HM
  • 2,539
  • 3
  • 25
  • 40
  • 4
    This did fix running from command line (I'm macOS Catalina as well), however it did not work on a variety of CIs – yo.ian.g Jan 25 '20 at 02:20
  • 1
    I read that the recommended solution was just a "workaround", and even the second most recommended solution was insecure. I'm also running on macOS Catalina and your solution worked well for me. This seems the best solution, since it doesn't compromise security nor is it also just a temporary workaround. – pizzae Apr 23 '20 at 11:05
  • Solved an issue I was having with `yarn` https://stackoverflow.com/questions/70659269/vercel-deploy-of-my-nextjs-app-with-font-awesome-pro-is-returning-a-401-build-er – Isaac Tait Jan 27 '22 at 14:38
14

If you just set your ~/.profile for the first time (OSX, Ubuntu) and added this line: export NPM_TOKEN="XXXXX-XXXXX-XXXXX-XXXXX". Then you must enter this line to the terminal afterward:

source ~/.profile
dang
  • 1,549
  • 1
  • 20
  • 25
  • If you are using a private npm package, you also need to login using `npm login`, set your username, password, email, and OTP if required. Then after logging in you can run npm/yarn commands – OzzyTheGiant Apr 10 '23 at 18:01
7

Running npm install in an IDE (like WebStorm) was my problem. I added the NPM_TOKEN environment variable to .bash_profile and restarted my Terminal, but not my IDE! The IDE did not pick up the changes to the environment until I restarted it as well.

Jordan Dodson
  • 415
  • 5
  • 5
  • From my understanding, terminal tabs/windows just run/parse bash_profile on start, meaning any changes to the files need to be run `source ~/.bash_profile` in existing windows/tabs in order for it to be re-parsed. Whenever I change the file, I can, from VSCode terminal, run source and it'll reinitialize with the new one, not needing to actually kill the IDE. – RaphaelDDL Jun 15 '22 at 18:20
  • Ok so NPM_TOKEN needed to be in the terminal's environment. Thanks, I got my setup in Docker through this error too by adding NPM_TOKEN to `services.serviceName.environment` – Looi Jul 28 '22 at 13:58
3

The following worked for me. I had to place

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion

AFTER the line where i specify

export NPM_TOKEN='mytoken'
Victor Ramos
  • 175
  • 3
  • 11
2

Im my case moving the export of the token inside my .zsh (or .bash_profile) to the top of the file fixed the problem because it has been initialised too late before.

chrisby
  • 834
  • 7
  • 15
2

I fixed it by setting NPM_TOKEN=""

In github action, i set the env:

jobs:
  build:
    runs-on: ubuntu-latest
    env:
      NPM_TOKEN: ""
    # ....
Abdennour TOUMI
  • 87,526
  • 38
  • 249
  • 254
2

I fixed this via passing a docker build arg as

ARG NPM_TOKEN
ENV NPM_TOKEN=$NPM_TOKEN
ENV NPM_CONFIG_TOKEN=$NPM_TOKEN

My scoped registry line with authToken wasn't being read properly inside my docker container. When running inside the container and invoking npm config list is didn't register.

So setting this variable : NPM_CONFIG_TOKEN and running npm config list registers it under a token key in the config.

jrowinsk3d
  • 21
  • 3
1

https://www.runoob.com/linux/linux-shell-variable.html replace

'//registry.npmjs.org/:_authToken=${NPM_TOKEN}'

with

'//registry.npmjs.org/:_authToken='${NPM_TOKEN}
summer
  • 21
  • 2
1

I got this issue while trying to setup a CI/CD job in Gitlab. I eventually found out that the error was caused because the variable that was throwing the error was set to a protected variable.

I changed it under Settings > CI / CD > Variables.

Jordi
  • 3,041
  • 5
  • 17
  • 36
0

For people on Ubuntu coming from google:

  • nano ~/.bash_aliases
  • export NPM_TOKEN="PUT_YOUR_TOKEN_HERE"
  • CTRL+X to exit
  • Y to save
fIwJlxSzApHEZIl
  • 11,861
  • 6
  • 62
  • 71
0

I am also getting this problem but I find a solution when I am pushing my repo on Heroku so I notice that Heroku run the command react-script start or build

//registry.npmjs.org/:_authToken=${NPM_TOKEN}

so this syntax didn't give the error but when I use the same syntax in my system and run the command it gives me. Because usually when we run in our system we use cmd npm or yarn but if you use react-script then it will not gives an error

Aman Gupta
  • 45
  • 5
0

On Windows while using git bash, setting a regular Windows environment variable worked for me. This answer helped setting an environment variable in Git Bash

Gabriel Wamunyu
  • 734
  • 9
  • 25
0

In case of windows and visual studio code - just restart your visual studio, it helps.

Also, how to set this environment variable on windows?

open Registry Editor, and follow \HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment, and create there another one "string value" with your token or whatever you need.

Nigrimmist
  • 10,289
  • 4
  • 52
  • 53
0

For mac

vim ~/.bash_profile

add export NPM_TOKEN=XXXXX-XXXXX-XXXXX-XXXXX

source ~/.bash_profile

also, add the below entry in the .zshrc file to apply the profile when a new terminal tab/window is opened.

if [ -f ~/.bash_profile ]; then
  . ~/.bash_profile
fi
Jineesh
  • 11,187
  • 5
  • 24
  • 25
0

Using AWS CODEARTIFACT

If you use docker, you need to add this to your Dockerfile

...
ARG CODEARTIFACT_AUTH_TOKEN
...
RUN export CODEARTIFACT_AUTH_TOKEN=$CODEARTIFACT_AUTH_TOKEN
RUN npm i
...

This is the .npmrc file

registry=https://sidanmor-codeartifact-main-112233.d.codeartifact.eu-west-1.amazonaws.com/npm/js-utils/
//https://sidanmor-codeartifact-main-112233.d.codeartifact.eu-west-1.amazonaws.com/npm/js-utils/:always-auth=true
//https://sidanmor-codeartifact-main-112233.d.codeartifact.eu-west-1.amazonaws.com/npm/js-utils/:_authToken=${CODEARTIFACT_AUTH_TOKEN}
registry=http://registry.npmjs.org

And the build command will be:

docker build --build-arg CODEARTIFACT_AUTH_TOKEN=xxxyyyzzz . --tag my-tag
sidanmor
  • 5,079
  • 3
  • 23
  • 31
0

For anyone using npm-run-all running into this issue that:

  • Doesn't want to remove or modify their .npmrc file (because the syntax is actually ok)
  • Doesn't want to add the variable in question into their shell profile
  • Doesn't want to set the variable before every single script as "build": "NPM_TOKEN=... ..."

I found that when using npm-run-all any scripts using run-p or run-s that use other scripts (either directly or indirectly) that use the form npm run <SCRIPT> will parse the .npmrc configuration file, which in turn will cause errors if variables are not set.

To fix this, all you need to do is convert any scripts that are used, directly or indirectly by scripts using run-s or run-p to use run-s

Let's take this as an example:

...
"scripts": {
    "dev": "run-s build*",
    "build:js": "...",
    "build:css": "...",
    "predev": "npm run clean",
    "clean": "rm -rf ./dist ./build"
}
...

Although this script does not call predev directly, it will be run before dev and this will cause configuration to be read, throwing the error

Instead, change it as follows:

...
"scripts": {
    "dev": "run-s build*",
    "build:js": "...",
    "build:css": "...",
    "predev": "run-s clean",
    "clean": "rm -rf ./dist ./build"
}
...

where predev now uses run-s instead of npm run

0

I had the same issue on Macbook pro. Actually the issue is with the naming. Previously i added my token to my env file as below

export GITHUB_TOKEN="xxxx-xxxx-xxxx"

Solved

Solved by changing the name to

export GITHUB_ACCESS_TOKEN="xxxx-xxxx-xxxx"

Conclution

When you define access tokens it is better to name it as **_ACCESS_TOKEN so the npm can identify it correctly.

Nipun Ravisara
  • 3,629
  • 3
  • 20
  • 35
-3

you can also replace the ${NPM_TOKEN} with your own GitHub generated personal token

Akki
  • 1
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Mar 20 '22 at 02:28