You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Codex plugin commands fail with command not found: node on Mac App #105
When using the Codex plugin in Claude Code on macOS, all !-pattern commands (/codex:status, /codex:result, /codex:cancel) and lifecycle hooks fail with:
(eval):1: command not found: node
Root cause: The plugin's !-pattern commands and hooks invoke node without an absolute path. The shell environment used for !-commands and hooks does not load shell init files (.zshenv, .zshrc), so only the minimal system PATH (/usr/bin:/bin:/usr/sbin:/sbin) is available. On macOS, Node.js is typically installed in /usr/local/bin or /opt/homebrew/bin, neither of which is in that minimal PATH.
Affected files:
commands/status.md, commands/result.md, commands/cancel.md — !-commands use bare node
hooks/hooks.json — all three hooks (SessionStart, SessionEnd, Stop) use bare node
Workaround: Replace node with /usr/local/bin/node in all affected files and update allowed-tools: Bash(node:) to Bash(/usr/local/bin/node:). This fix is lost on plugin updates since the files live in the plugin cache.
Suggested fix: Use an absolute path, #!/usr/bin/env node, or resolve the node binary path at plugin install time. Alternatively, ensure the !-command shell inherits a reasonable PATH (e.g. by sourcing ~/.zshenv).
Hit this too — confirming on Apple Silicon + Claude.app desktop (launchd-spawned, so bash -c inherits only /usr/bin:/bin:/usr/sbin:/sbin, and .zshenv doesn't help because the Bash tool isn't zsh).
Additional affected files not listed in the original report:
agents/codex-rescue.md — the subagent definition invokes bare node
commands/rescue.md — same, plus allowed-tools: Bash(node:*) needs updating to match
Both of the above also exist under plugins/marketplaces/openai-codex/plugins/codex/ and need the same fix
The rescue path has a worse failure mode than the other commands. When /codex:rescue or the codex-rescue subagent fails to spawn because node isn't found, Claude Code doesn't surface the error — instead it violates the subagent spec and hallucinates a response as if it had actually consulted Codex. The user sees a plausible-looking "Codex says..." reply that was entirely fabricated. This is significantly more dangerous than the visible command not found from /codex:status etc., because there's no signal that anything went wrong.
Local workaround I've been running since 2026-04-07: replace bare node with /opt/homebrew/bin/node (or /usr/local/bin/node on Intel) in all 4 rescue files, and update allowed-tools in commands/rescue.md to include Bash(/opt/homebrew/bin/node:*). Has to be re-applied after every /plugin update.
Preferred upstream fix (in priority order):
Resolve the node path at plugin install time and write it into the command files
Use process.execPath from within any already-running Node context and pass it down
Shell out to /usr/bin/env node in the !-pattern commands (less robust — /usr/bin/env will still fail to find node if PATH is minimal)
Option 1 is the cleanest since it handles Intel Mac, Apple Silicon, nvm/mise/volta, and Linux uniformly.
Still reproducible on plugin v1.0.6 (Claude Code, macOS).
Trigger: the failure only appears in launch contexts whose inherited PATH lacks the Homebrew prefix — notably when Claude Code is started by macOS itself (Desktop app / launchd, whose default PATH is /usr/bin:/bin:/usr/sbin:/sbin) and over non-interactive SSH. Terminal-launched sessions inherit a full PATH and never see it, which is why this reads as intermittent.
Mechanism: hooks are executed via sh -c and inherit the parent environment verbatim — the docs state this — so a bare node in hooks/hooks.json resolves only if the launching process already had Homebrew on PATH. Both session-lifecycle-hook.mjs (SessionStart/SessionEnd) and stop-review-gate-hook.mjs are affected, and per this thread the !-pattern commands are too.
Workaround that does not involve editing the plugin cache (the cache edit works but is silently discarded when a new version directory is installed and installPath repoints): set a complete PATH in the env map of user settings.json. Verified: hook processes, MCP server processes, and the Bash tool all then receive that value. Two caveats worth knowing — it replaces PATH rather than prepending, so the value must be complete; and env's scope is not currently documented as covering hooks, so this is empirical rather than guaranteed.
A fix at the plugin's end — resolving an absolute interpreter path at install time, or documenting the PATH requirement — would remove the need for either workaround.
Activity
7vf7gcpwsy-create commentedon Apr 11, 2026
Hit this too — confirming on Apple Silicon + Claude.app desktop (launchd-spawned, so
bash -cinherits only/usr/bin:/bin:/usr/sbin:/sbin, and.zshenvdoesn't help because the Bash tool isn't zsh).Additional affected files not listed in the original report:
agents/codex-rescue.md— the subagent definition invokes barenodecommands/rescue.md— same, plusallowed-tools: Bash(node:*)needs updating to matchplugins/marketplaces/openai-codex/plugins/codex/and need the same fixThe rescue path has a worse failure mode than the other commands. When
/codex:rescueor thecodex-rescuesubagent fails to spawn becausenodeisn't found, Claude Code doesn't surface the error — instead it violates the subagent spec and hallucinates a response as if it had actually consulted Codex. The user sees a plausible-looking "Codex says..." reply that was entirely fabricated. This is significantly more dangerous than the visiblecommand not foundfrom/codex:statusetc., because there's no signal that anything went wrong.Local workaround I've been running since 2026-04-07: replace bare
nodewith/opt/homebrew/bin/node(or/usr/local/bin/nodeon Intel) in all 4 rescue files, and updateallowed-toolsincommands/rescue.mdto includeBash(/opt/homebrew/bin/node:*). Has to be re-applied after every/plugin update.Preferred upstream fix (in priority order):
process.execPathfrom within any already-running Node context and pass it down/usr/bin/env nodein the !-pattern commands (less robust —/usr/bin/envwill still fail to find node if PATH is minimal)Option 1 is the cleanest since it handles Intel Mac, Apple Silicon, nvm/mise/volta, and Linux uniformly.
fix(broker): bypass local codex availability check under --require-br…
astradevkin commentedon Aug 19, 2026
Still reproducible on plugin v1.0.6 (Claude Code, macOS).
Trigger: the failure only appears in launch contexts whose inherited PATH lacks the Homebrew prefix — notably when Claude Code is started by macOS itself (Desktop app / launchd, whose default PATH is
/usr/bin:/bin:/usr/sbin:/sbin) and over non-interactive SSH. Terminal-launched sessions inherit a full PATH and never see it, which is why this reads as intermittent.Mechanism: hooks are executed via
sh -cand inherit the parent environment verbatim — the docs state this — so a barenodeinhooks/hooks.jsonresolves only if the launching process already had Homebrew on PATH. Bothsession-lifecycle-hook.mjs(SessionStart/SessionEnd) andstop-review-gate-hook.mjsare affected, and per this thread the!-pattern commands are too.Workaround that does not involve editing the plugin cache (the cache edit works but is silently discarded when a new version directory is installed and
installPathrepoints): set a completePATHin theenvmap of usersettings.json. Verified: hook processes, MCP server processes, and the Bash tool all then receive that value. Two caveats worth knowing — it replaces PATH rather than prepending, so the value must be complete; andenv's scope is not currently documented as covering hooks, so this is empirical rather than guaranteed.A fix at the plugin's end — resolving an absolute interpreter path at install time, or documenting the PATH requirement — would remove the need for either workaround.