When a Mac App Can't Find a CLI Your Terminal Can Run

A short debugging note on why a macOS GUI app could not find `codex` even though the terminal could, and how inspecting the app process `PATH` led to a launchd-level fix.

macOSCLIPATHlaunchd

I hit a small but useful macOS debugging problem: an app reported that codex was not on PATH, even though codex --version worked in my terminal.

PATH is the colon-separated list of directories a process searches when you ask it to run a command. The catch on macOS is that Finder/Dock-launched apps normally inherit their launch environment from launchd, not from .zshrc, .zprofile, or nvm shell setup.

In my terminal, codex resolved to two places:

/opt/homebrew/bin/codex
~/.nvm/versions/node/v24.15.0/bin/codex

The GUI app, however, had been launched with this minimal app PATH:

/usr/bin:/bin:/usr/sbin:/sbin

That path excludes both Homebrew and nvm, so the app's codex --version probe failed. The npm-install suggestion was misleading; Codex was already installed and runnable. The app just could not see it.

Symlinks were a distraction in this case. A symlink only helps if it lives in a directory the app already searches, and this app was not searching /opt/homebrew/bin, the nvm bin directory, or /usr/local/bin.

Debug the App, Not the Shell

The useful move was to inspect the live app process:

ps eww -p <pid>

<pid> is the process ID of the running app. You can find it with pgrep, Activity Monitor, or any process-listing tool.

For a controlled launch, this started the app with an explicit path:

open --env PATH=/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin -a "LLM Wiki"

With that environment, the app detected /opt/homebrew/bin/codex. That confirmed the problem was the app process environment, not the Codex install.

Fix the Launch Environment

For the current login session, launchctl setenv PATH ... can update the user launchd environment:

launchctl setenv PATH '/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin'

In this session, that setting was visible in launchd, but it was still insufficient for this app's normal service launch, which kept starting with the minimal Apple path.

As a one-shot proof and current-session fix, launchctl debug can force the next launch of an app service to use a specific environment:

sudo launchctl debug ... --environment PATH=/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

For the durable macOS-supported setting, the relevant command was:

sudo launchctl config user path '/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin'

macOS reported that a reboot was required. After reboot, normal Finder and Dock launches should inherit the configured user-domain path, though I had not tested the post-reboot behavior yet.

The app ended up finding the Homebrew-managed codex at /opt/homebrew/bin/codex, which is the better target for this GUI app. It does not depend on nvm shell initialization or a specific Node version directory.

When a macOS GUI app says a CLI tool is missing but your terminal can run it, check the live app process PATH before reinstalling the tool or adding symlinks.