← BlogEngineering

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: 243

The 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 without sudo.
  • 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.

Keep reading

More build logs.

All posts →
  1. Story2 November 2026FundingView: 11 days, Claude in a browser tab, and a CSV on GitHub4 min
  2. Engineering2 November 2026Our dictation app grew to 35 GB of RAM. The first fix was wrong.5 min
  3. Infrastructure2 November 2026Three deploy mistakes that broke our production, and the rule each one left5 min