[BUG] Claude Code always uses system version of node, rather than project-specific version installed via nodenv
Environment
- Platform (select one):
- [x] Anthropic API
- [ ] AWS Bedrock
- [ ] Google Vertex AI
- [ ] Other: <!-- specify -->
- Claude CLI version:
0.2.45 (Claude Code) - Operating System:
OSX 15.3.2 - Terminal:
Kitty 0.37.0 with fish shell 3.7.1
Bug Description
Claude code always uses the system version of node, which is incorrect if there is a more specific project version it should be using.
I am using nodenv to manage my node version. This means I have nodenv installed, and a .node-version file in the root of my project. My shell will automatically pick this up, and switch to the correct version of node.
The same is true for other tools like rbenv, phpenv, pyenv, goenv etc.
All of these tools are bootstrapped in your shell, i.e. in ~/.config/fish/config.fish I have
status --is-interactive; and source (rbenv init -|psub)
status --is-interactive; and source (phpenv init -|psub)
status --is-interactive; and source (nodenv init -|psub)
status --is-interactive; and source (pyenv init -|psub)
status --is-interactive; and source (goenv init -|psub)
Claude Code claims (to me) to be running zsh shell, and is not bootstrapping any of these tools.
I asked Claude how it could boostrap these tools, and it said it would remember to do so for the future using
export PATH="$HOME/.nodenv/bin:$PATH" && eval "$(nodenv init -)"
Except that it doesn't seem to actually work. I've tried adding this to my CLAUDE.md, but that also seems to not have effect:
````markdown
Environment
Ensure you run any npm commands with the correct version of Node.
nodenv is used locally to manage Node
versions. The .node-version file in the project root specifies the correct
version.
Make sure you setup the correct version of Node with nodenv:
export PATH="$HOME/.nodenv/bin:$PATH" && eval "$(nodenv init -)"
````
Steps to Reproduce
Have nodenv installed and system node installed, but have different versions.
Note that starting Claude and asking it to node --version, will output system version of node, rather than the project-specific version dictated by .node-version file in the project.
Expected Behavior
If there is a .node-version file it should be using that version of node, especially if I've already instructed it on how to switch to the correct node version via CLAUDE.md
Actual Behavior
It used the system version of node, and seemed to ignore instructions on how to switch to project-specific nodenv version of node.
Additional Context
<!-- Add any other context about the problem here, such as screenshots, logs, etc. -->
10 Comments
The fix here is to write a .zshrc that includes the aliases and env vars that you want claude to have. Claude can't operate fish shell.
I added the setup to
.zshrcand it worked, cheers@asgeo1 @wolffiex Can you give an example of the fix you described?
@bhrutledge it depends on your setup. the idea is that claude code will start bash or zsh (you can have it check which) and will source the .bashrc or .zshrc in your home directory. any config that you want to claude to have can go there
@wolffiex Thanks, but I'm still not quite following. Happy to read the docs if you can point me to them.
Do you mean that Claude Code automatically starts a shell (e.g.
npm)? I use ZSH. How do I have Claude Code check which shell it's using, and/or switch to the one I prefer?Does the sourcing happen automatically? What "config" would I put in there to ensure that
npmuses the currentnodenvversion? I've already haveeval "$(nodenv init -)"in my .zshrc.I recognize that this issue has been closed, but I just wanted to chime in real quick. In my personal
.zshsetup, I'm pretty meticulous and obsessive about its organization and launch speed. So I have it set up such that there is achpwdhook with which I use to detect the nature of the directory I'm in (or changing to). If it detects ruby, node, python, it loads the appropriate*env(load_rbenv, andload_pyenv, etc) manager. In other words, each shell instance doesn't initialize the world, which leaves poor Claude at a disadvantage.Is there a way to detect that it's a Claude Agent calling for a new shell, and thus I could choose to load the world for it, out of laziness?
This is what I've come up with for now. Still sucks to have to reinit a new shell for each command.
And instruct
claudeto callsource ~/bin/claude && [whatever command]yes, condition on
CLAUDE_CODEexisting or equaling 1Sadly, that does not work for me.
!image
Just wasted an hour on this for anyone who comes across this.
Looks like the root issue in my case is https://github.com/modelcontextprotocol/servers/issues/64 but, the workaround is pretty easy. I updated the
PATHenv variable and thecommandto specify the node version directly. Just replace the$(USER)with your username and the node version/path if applicable.This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.