nvm: NVM fails to load within nested shell

  • Operating system and version: macOS High Sierra 10.13.1 (17B48)

  • nvm debug output:

Stefans-MacBook-Pro:~ stefan$ nvm debug
nvm --version: v0.33.6
$TERM_PROGRAM: Apple_Terminal
$SHELL: /bin/bash
$HOME: /Users/stefan
$NVM_DIR: '$HOME/.nvm'
$PREFIX: ''
$NPM_CONFIG_PREFIX: ''
$NVM_NODEJS_ORG_MIRROR: ''
$NVM_IOJS_ORG_MIRROR: ''
shell version: 'GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin17)'
uname -a: 'Darwin 17.2.0 Darwin Kernel Version 17.2.0: Fri Sep 29 18:27:05 PDT 2017; root:xnu-4570.20.62~3/RELEASE_X86_64 x86_64'
OS version: Mac 10.13.1 17B48
curl: /usr/bin/curl, curl 7.54.0 (x86_64-apple-darwin17.0) libcurl/7.54.0 LibreSSL/2.0.20 zlib/1.2.11 nghttp2/1.24.0
wget: not found
git: /usr/bin/git, git version 2.13.6 (Apple Git-96)
grep: /usr/bin/grep, grep (BSD grep) 2.5.1-FreeBSD
awk: /usr/bin/awk, awk version 20070501
sed: illegal option -- -
usage: sed script [-Ealn] [-i extension] [file ...]
       sed [-Ealn] [-i extension] [-e script] ... [-f script_file] ... [file ...]
sed: /usr/bin/sed, 
cut: illegal option -- -
usage: cut -b list [-n] [file ...]
       cut -c list [file ...]
       cut -f list [-s] [-d delim] [file ...]
cut: /usr/bin/cut, 
basename: illegal option -- -
usage: basename string [suffix]
       basename [-a] [-s suffix] string [...]
basename: /usr/bin/basename, 
rm: illegal option -- -
usage: rm [-f | -i] [-dPRrvW] file ...
       unlink file
rm: /bin/rm, 
mkdir: illegal option -- -
usage: mkdir [-pv] [-m mode] directory ...
mkdir: /bin/mkdir, 
xargs: illegal option -- -
usage: xargs [-0opt] [-E eofstr] [-I replstr [-R replacements]] [-J replstr]
             [-L number] [-n number [-x]] [-P maxprocs] [-s size]
             [utility [argument ...]]
xargs: /usr/bin/xargs, 
nvm current: v8.8.1
which node: $NVM_DIR/versions/node/v8.8.1/bin/node
which iojs: 
which npm: $NVM_DIR/versions/node/v8.8.1/bin/npm
npm config get prefix: $NVM_DIR/versions/node/v8.8.1
npm root -g: $NVM_DIR/versions/node/v8.8.1/lib/node_modules
  • nvm ls output:
Stefans-MacBook-Pro:~ stefan$ nvm ls
        v6.10.3
->       v8.8.1
         system
default -> node (-> v8.8.1)
node -> stable (-> v8.8.1) (default)
stable -> 8.8 (-> v8.8.1) (default)
iojs -> N/A (default)
lts/* -> lts/boron (-> N/A)
lts/argon -> v4.8.5 (-> N/A)
lts/boron -> v6.11.5 (-> N/A)
  • How did you install nvm? (e.g. install script in readme, homebrew): install script

  • What steps did you perform? install nvm install latest node (currently 8.8.1) execute bash -l

  • What happened? nvm fails to load with the following error:

nvm is not compatible with the npm config "prefix" option: currently set to "/usr/local"
Run `npm config delete prefix` or `nvm use --delete-prefix v8.8.1 --silent` to unset it.
  • What did you expect to happen? nvm to load without issues

  • Is there anything in any of your profile files (.bashrc, .bash_profile, .zshrc, etc) that modifies the PATH? yes, google-sdk and nvm

  • MORE INFO So I have been doing some investigation and it seems that when you execute bash -l the PATH environment variable retains the path to the nvm configured node instance.

You can see this by adding the following line to the top of your ~/.bash_profile:

printenv

Result:

PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/stefan/.nvm/versions/node/v8.8.1/bin:/Users/stefan/google-cloud-sdk/bin

Seems that nvm can’t handle that when run inside a nested shell.

  • WORKAROUND Currently my workaround is to reset the path by adding the following line inside my ~/.bash_profile at the very top before anything else:
PATH="/usr/local/bin:$(getconf PATH)"

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 33
  • Comments: 49 (18 by maintainers)

Commits related to this issue

Most upvoted comments

For me, it only worked after fully uninstalling the system installation of node:

brew uninstall node brew prune sudo rm -rf /usr/local/{lib/node{,/.npm,_modules},bin,share/man}/{npm*,node*,man1/node*}

Then nvm ls shouldn’t have any system installed node entry. A new tmux session worked fine after that as well.

Interesting. You identified the issue. I had brew installed heroku on both my machines and it has node as a dependency (thus node and npm are installed to /usr/local/bin in the background). I deleted node but npm stuck around in /usr/local/bin/npm. Having deleted npm I don’t see this issue anymore.

I came across the same error message. The first time I tried to install nodejs/npm was with homebrew. I did brew install npm. That version was not working for me and google search indicated that a better way to manage nodejs is using nvm. So I uninstalled using brew uninstall npm. And then did brew install nvm and nvm …
Things worked fine and only came across the issue trying to use tmux. Turns out ‘brew uninstall npm’ removed nodejs but left links for /usr/local/bin/npm.

npm -> /usr/local/lib/node_modules/npm/bin/npm-cli.js
npx -> /usr/local/lib/node_modules/npm/bin/npx-cli.js

Once I removed the links and /usr/local/lib/node_modules directory, the problem went away.

Just commenting in case it can help someone else that might have done the same as me.

Deleting /usr/local/bin/npm from my previous homebrew install fixed this for me. I had been getting this error only while using tmux on Mac.

Hi all, sorry for the long silence.

I didn’t have access to a macOS machine. I now have access to one and I believe I’ve solved the issue in PR #1830.

This is tricky. The bug is in the OS, but the OS hasn’t cared for nearly 5 years, and it’s a very widely used OS amongst nvm’s user base.

The argument for doing “change path” in favour of “prepend path” was specifically to avoid the kind of issues that Apple is creating by prepending instead of appending (which is what their docs say they do).

I feel like 2 wrongs don’t make a right (in this case, better than just 1 wrong, but still not right).

I agree that hard-coding those paths is not a great solution. Certainly, the user can configure which directories path_helper actually prepends. But, nvm is not the only utility that has to deal with this. In my research about this macOS bug, I came across issues reported to rvm and chruby also. I’m sure there are other utilities that have been impacted by this also. I’m going to have a look at how these and other utilities have handled this problem and whether their solutions might work for us.

Similar results here but not in a nested shell:

✗ echo $SHLVL
1
➜  ~ git:(master) ✗ echo $PATH ; type nvm ; which node ; which npm ; nvm debug 


/usr/local/git/bin:/sw/bin:/usr/local/bin:/usr/local:/usr/local/sbin:/usr/local/mysql/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Frameworks/Python.framework/Versions/2.7/bin:/usr/local/bin
nvm is a shell function from /Users/r631947/.nvm/nvm.sh
/usr/local/bin/node
/usr/local/bin/npm
nvm --version: v0.33.6
$TERM_PROGRAM: Apple_Terminal
$SHELL: /bin/zsh
$HOME: /Users/r631947
$NVM_DIR: '$HOME/.nvm'
$PREFIX: ''
$NPM_CONFIG_PREFIX: ''
$NVM_NODEJS_ORG_MIRROR: ''
$NVM_IOJS_ORG_MIRROR: ''
shell version: 'zsh 5.0.8 (x86_64-apple-darwin15.0)'
uname -a: 'Darwin 15.6.0 Darwin Kernel Version 15.6.0: Sun Jun 4 21:43:07 PDT 2017; root:xnu-3248.70.3~1/RELEASE_X86_64 x86_64'
OS version: Mac 10.11.6 15G1611
curl: /usr/bin/curl, curl 7.43.0 (x86_64-apple-darwin15.0) libcurl/7.43.0 SecureTransport zlib/1.2.5
wget: not found
git: /usr/bin/git, git version 2.10.1 (Apple Git-78)
grep: grep: aliased to grep  --color=auto --exclude-dir={.bzr,CVS,.git,.hg,.svn} (grep --color=auto --exclude-dir={.bzr,CVS,.git,.hg,.svn}), grep (BSD grep) 2.5.1-FreeBSD
awk: /usr/bin/awk, awk version 20070501
sed: illegal option -- -
usage: sed script [-Ealn] [-i extension] [file ...]
       sed [-Ealn] [-i extension] [-e script] ... [-f script_file] ... [file ...]
sed: /usr/bin/sed, 
cut: illegal option -- -
usage: cut -b list [-n] [file ...]
       cut -c list [file ...]
       cut -f list [-s] [-d delim] [file ...]
cut: /usr/bin/cut, 
basename: illegal option -- -
usage: basename string [suffix]
       basename [-a] [-s suffix] string [...]
basename: /usr/bin/basename, 
rm: illegal option -- -
usage: rm [-f | -i] [-dPRrvW] file ...
       unlink file
rm: /bin/rm, 
mkdir: illegal option -- -
usage: mkdir [-pv] [-m mode] directory ...
mkdir: mkdir: aliased to mkdir -pv (mkdir -pv), 
xargs: illegal option -- -
usage: xargs [-0opt] [-E eofstr] [-I replstr [-R replacements]] [-J replstr]
             [-L number] [-n number [-x]] [-P maxprocs] [-s size]
             [utility [argument ...]]
xargs: /usr/bin/xargs, 
nvm current: system
which node: /usr/local/bin/node
which iojs: iojs not found
which npm: /usr/local/bin/npm
npm config get prefix: /usr/local
npm root -g: /usr/local/lib/node_modules

I solved this by downgrading to 0.33.4. I had to get rid of $NVM_DIR/bash_completion in my profile to be compatible with oh-my-zsh.

@dylansm You saved my day! I just renamed my mac default node command using mv /usr/local/bin/node node.bak. Works for me!

thanks @msutherl I rec’d a message to update Yarn, and then blindly followed the update instructions to update yarn via brew. so homebrew installed yarn and node. I removed node, npm, and yarn then reinstalled yarn without node… brew install yarn --ignore-dependencies In external terminal everything worked fine, but in VScode it was saying i didn’t have node installed. removing npm from usr/local/bin/npm cleared it up thanks!

@danielcondemarin your solution works except it stopped all the node related service i have defined in launchd since they were all using the system version of node…

From the perspective of this thread - and I think of nvm use in general - removing system nodes is a feature, not a bug.

Can confirm @oblutak’s fix works if you did brew install node before installing nvm instead of brew install npm. Just make sure you uninstall node using brew instead of npm!

Also solved this by installing v0.33.4, like @jcollum suggested. Used the git install method described here, but checked out v0.33.4 manually.

@rwjblue easy to miss in a big thread

Maybe github should have a “This fixed things for me” reaction?

@gsong it would be very helpful to link directly to the comment.

@charsleysa I know why nvm is throwing this error. In your subshell, somehow the /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin part of your PATH has been moved from the end of the PATH to the start.

  • When nvm is then started, it calls nvm_change_path (my contribution changed it to this from nvm_prepend_path), which modifies the nvm-relevant part of the path in place.
  • Nvm then checks the current npm prefix by asking npm what it is. Since /usr/local/bin/npm now has precendence, it reports /usr/local/bin.
  • Nvm then checks whether the current prefix as reported by npm is in the directory tree of the current nvm node version (at this stage, the installation directory of the node version your default nvm alias resolves to).
  • The prefix is not part of that tree, so it deactivates itself (calling nvm_strip_path in the process, which is why there’s no nvm-related path in your subshell’s PATH), and bails with the error you’re getting.

macOS’s /etc/profile (or /etc/zprofile) calls /usr/libexec/path_helper, which does the PATH switcheroo.

In the parent shell, the PATH doesn’t yet have an nvm dir in it, so by the time nvm runs, it prepends its directory to the path. But in the subshell, PATH has been reconfigured by macOS to put any non-system directories at the end and we have the problem.

@ljharb I’d like to explore ways to modify nvm_change_path, probably that it makes sure that nvm’s directory is in front of any /usr, /bin, and /sbin directories.

I.e. it’ll replace the path in place, like it currently does, unless it’s being shadowed by system root executable directories, in which case it’ll prepend again. Sound good?

@charsleysa @dylansm Please can you paste the contents of your bash login rc files (including any system-wide login rc files that OS X/macOS might come with; also if e.g. ~/.bash_profile sources ~/.bashrc also include ~/.bashrc).

@dylansm I’m not 100% sure what’s happening yet, but it’s almost like in the sub shell NVM is finding a local npm but not a local node.

which node: node not found
which iojs: iojs not found
which npm: /usr/local/bin/npm

This is odd… node and npm (and recently npx) are installed together. Did you remove /usr/local/bin/node without removing /usr/local/bin/npm? Is there a /usr/local/bin/node on your system? @charsleysa did you paste the output of nvm debug of the parent shell or the nested shell? If it was the parent shell, please paste the output of nvm debug in the subshell.

Also of use (I’m not a Mac user) would be knowing where /usr/local/bin/{node,npm} come from. Are they installed by default by Apple? Are they installed by Homebrew? The official Node installer?

I suspect that somehow, in both these cases, /usr/local/bin/node was removed, but /usr/local/bin/npm was left behind. In addition, I suspect that the rc files that get read on a new login shell are prepending to the inherited path instead of resetting it (which is the default behaviour that at least the Debian maintainers have set in /etc/profile).

Thanks a lot @danielcondemarin and others. Worked also for me and make me understand better how it works !

Thanks @danielcondemarin! Worked for me 😄

@jcollum OMZ sets a bunch of options that often break things; if you can file a separate issue for that, we can try to figure out which zsh option is causing the problem, and maybe find a way nvm can work around it.

@charsleysa i’m confused how in your parent shell /Users/stefan/.nvm/versions/node/v8.8.1/bin is the first thing in your PATH, but which node and which npm locate your system node and npm first. That seems broken (before even making a nested shell). What’s nvm current print out, before and after nvm use 8.8.1?