Why “Update Codex” failed inside GHZ Code and worked in the Terminal
GHZ Code can install and update the coding agents it launches, like Claude Code and OpenAI Codex, from a button in the app. In October 2026 the Update button for Codex started failing on my own Mac:
npm error EACCES: permission denied, mkdir '/usr/local/lib/node_modules/@openai'
failed with status exit status: 243The same command worked in the Terminal. Same machine, same user, same npm install -g @openai/codex.
Two Node installs on one Mac
The machine had two copies of Node, which is common:
- One from the official installer in
/usr/local, owned by root. Its global folder cannot be written withoutsudo. - One from Homebrew in
/opt/homebrew, owned by the user. Codex was installed here.
In the Terminal, Homebrew comes first in the PATH, so npm meant the Homebrew one and everything worked.
The app changed the order
Apps opened from the Dock do not get your shell’s PATH. To find agents installed in the usual places, GHZ Code added a list of folders to the shell it starts. It added them in front:
PATH="~/.cargo/bin:~/.local/bin:/usr/local/bin:/opt/homebrew/bin:$PATH"That put /usr/local/bin before Homebrew. Inside the app, npm resolved to the root-owned copy, which tried to write to /usr/local/lib/node_modules, and failed.
The fix, in two releases
Version 0.3.14 appends our folders at the end of the PATH instead of the start, so the order from your login shell always wins:
export PATH="$PATH:$GHZCODE_AGENT_PATH"Version 0.3.16 goes further. Before updating an agent, the app finds where that agent actually lives (command -v, then the real path behind any symlink) and updates it with the package manager that installed it: that npm prefix, the Homebrew formula or cask, or the vendor’s own installer. If the folder is still not writable, it shows a readable message with the command to run, instead of an npm stack trace.