Why does Codex use the system node installation over NVM? Using node v16 constantly

Open 💬 8 comments Opened Oct 15, 2025 by lightninglu10

What version of Codex is running?

codex-cli 0.46.0

Which model were you using?

gpt-5-codex-high

What platform is your computer?

Darwin 24.6.0 arm64 arm

What steps can reproduce the bug?

I'm trying to use codex and have it run CLI commands, but it always wants to run it in a node 16 environment. Why? Claude code doesn't do that. I have other node environments installed and I'm running codex from a node v20 environment, but it always thinks or is in a v16 environment

What is the expected behavior?

Codex runs in whatever environment you start it with

What do you see instead?

It only runs in v16

Additional information

_No response_

View original on GitHub ↗

8 Comments

Femoon · 9 months ago

I encountered the same problem on macOS. The workaround is to uninstall the system's Node, and then Codex will use the Node from NVM when executing CLI commands.

lightninglu10 · 9 months ago
I encountered the same problem on macOS. The workaround is to uninstall the system's Node, and then Codex will use the Node from NVM when executing CLI commands.

That is an awful workaround :(, hoping the Codex team can fix this!

System node is needed for a lot of random mac processes, just like the system python is.

nlothian · 9 months ago

This is really annoying.

I've found the following in my AGENTS.md works:

This app uses Node v22, which can be accessed via nvm. If you are getting the wrong node version then run nvm use 22, change to this directory and then run npm run <command> in the same shell session. It is very important that you run NVM and the NPM command in the same shell session. If it is in another session you get the wrong version of node.
wiegell · 8 months ago
This is really annoying. I've found the following in my AGENTS.md works: > This app uses Node v22, which can be accessed via nvm. > If you are getting the wrong node version then run nvm use 22, change to this directory and then run npm run <command> _in the same shell session_. It is very important that you run NVM and the NPM command in the same shell session. If it is in another session you get the wrong version of node.

Not working for processes that spawns subprocesses, e.g. Cypress

sharmilajesupaul · 6 months ago

This is a huge pain if you have to run any app or tool that needs a node version greater than 16, which is most things these days because v16 reached end of life in 2023 🫠

The worst part is that the agent will actually spend time trying to debug its own Node version before giving up and telling the user to run commands. Prefixing with nvm/fnm is a less destructive hack than uninstalling your system node, but it is a partial workaround.

This is still a considerable pain point and the workarounds are brittle. I'm guessing this will impede anyone working with codex in a JS/TS environment.

At minimum, it would help to clearly document the Node resolution behavior. Ideally, Codex should respect the Node version of the shell it’s launched from (or allow configuring this explicitly).

GHesericsu · 6 months ago

I'm still encountering the same issue with codex persistently using system node like v14 and have not found a good workaround that's sustainable.

a2f0 · 6 months ago

This is kind of a weird issue that I spent the better part of a day working on. The solution for me was to add the sourcing to ~/.zshenv (instead of ~/.zshrc or ~/.zprofile).

I also added this to ~/.zprofile:

# macOS /etc/zprofile uses path_helper after zshenv, which can drop shims/PATH.
if [[ "$(uname)" == Darwin ]]; then
  unset __ZSHENV_SOURCED
  source "$HOME/.zshenv"
fi
__ZSHENV_SOURCED=1

This worked for both nvm and rbenv for me (I was having problems with both).

jrencz · 5 months ago

In my case it defaults to the NVM's default (likely because it's a default on OS level), but if a project uses other it first fails, then it realizes what's wrong and works with NVM.

I'm using this in AGENTS.md on project level:

Runtime baseline is Node version defined by `.nvmrc` and `package.json` (`engines.node`)

So: wastes time, but isn't stuck.
Maybe that will be a progress to someone

(gpt-5.3-codex, Codex.app 26.212.1823 (661))