codex - 💡(How to fix) Fix Desktop app zsh snapshot export filter omits PATH, breaking Homebrew tools [2 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openai/codex#20220Fetched 2026-04-30 06:31:37
View on GitHub
Comments
2
Participants
2
Timeline
6
Reactions
0
Author
Timeline (top)
labeled ×4commented ×2

Root Cause

This appears Desktop-specific because the broken snapshot is masked when Codex is launched from a terminal whose parent environment already contains the desired PATH.

Code Example

zsh:1: command not found: gh

---

export -T PATH path=( /opt/homebrew/bin /usr/bin /bin ... )

---

[shell_environment_policy]
inherit = "all"
ignore_default_excludes = true
include_only = ["HOME", "LOGNAME", "PATH", "SHELL", "USER", "TMPDIR", "TEMP", "TMP"]

---

command=["/bin/zsh","-lc","gh --version"]
stderr="zsh:1: command not found: gh"
exit_code=127

---

Shell snapshot successfully created: ~/.codex/shell_snapshots/<thread-id>.tmp-...
RAW_BUFFERClick to expand / collapse

What version of the Codex App are you using (From “About Codex” dialog)?

26.422.71525

What subscription do you have?

API Key

What platform is your computer?

Darwin 25.4.0 arm64 arm

What issue are you seeing?

Codex Desktop shell commands can fail to find tools that are installed via Homebrew, for example gh, even though the same Codex config works when Codex is launched from a terminal.

My config uses shell_environment_policy.inherit = "all" and keeps PATH in include_only. For a CLI/terminal-launched Codex process, tool execution inherits the terminal PATH, which includes /opt/homebrew/bin. In the Desktop app, the app-server process is launched from the macOS GUI environment, so the inherited PATH does not include /opt/homebrew/bin.

Shell snapshots are supposed to bridge that gap by sourcing .zshrc and restoring the resulting shell environment before running the final non-interactive command. In this case, the app-server log shows the shell snapshot was created successfully, but the snapshot omitted the actual PATH export. A later gh --version tool call was logged as /bin/zsh -lc "gh --version" and failed with:

zsh:1: command not found: gh

The likely source is the zsh snapshot export/declare filter. zsh emits tied path parameters as:

export -T PATH path=( /opt/homebrew/bin /usr/bin /bin ... )

but the current filter only preserves simple export/declare -x/typeset -x lines whose parsed name looks like NAME=.... It parses the zsh line as something like -T PATH path, rejects it as an invalid variable name, and drops it. The snapshot succeeds, but does not restore PATH.

What steps can reproduce the bug?

  1. On macOS with zsh, install gh or another CLI tool under /opt/homebrew/bin.
  2. Configure PATH from ~/.zshrc, not from a global launchd environment.
  3. Use a Codex config that inherits PATH into tool execution, for example:
[shell_environment_policy]
inherit = "all"
ignore_default_excludes = true
include_only = ["HOME", "LOGNAME", "PATH", "SHELL", "USER", "TMPDIR", "TEMP", "TMP"]
  1. Launch Codex Desktop from the macOS app/Finder/Dock, not from a terminal.
  2. In a thread, run a command such as gh --version or command -v gh.

Observed in one Desktop-backed rollout:

command=["/bin/zsh","-lc","gh --version"]
stderr="zsh:1: command not found: gh"
exit_code=127
  1. Check app-server logs in ~/.codex/logs_2.sqlite: the shell snapshot had succeeded before the command ran, so this was not a snapshot timeout.
  2. Inspect a generated zsh snapshot under ~/.codex/shell_snapshots/*.sh: there is no top-level export PATH=..., declare -x PATH=..., or typeset -x PATH=...; PATH only appears incidentally inside captured function bodies.

What is the expected behavior?

Codex Desktop should behave the same as a terminal-launched Codex process under the same shell config. If .zshrc adds /opt/homebrew/bin to PATH and the zsh shell snapshot succeeds, subsequent shell commands should be able to resolve tools from that PATH.

The zsh snapshot should preserve tied exported path parameters such as export -T PATH path=(...), or otherwise normalize them into a sourceable scalar export PATH=... line before the final non-login/non-interactive shell command is executed.

Additional information

This appears Desktop-specific because the broken snapshot is masked when Codex is launched from a terminal whose parent environment already contains the desired PATH.

Relevant source locations from current openai/codex:

  • codex-rs/core/src/shell_snapshot.rs: zsh_snapshot_script() captures exports via export -p | awk ....
  • codex-rs/core/src/tools/runtimes/mod.rs: maybe_wrap_shell_lc_with_snapshot() sources the snapshot, then executes the original command with exec <shell> -c <script>.
  • Current tests only assert that the snapshot text contains PATH; this can pass when PATH appears inside captured function bodies even if the snapshot does not restore the PATH variable.

In the investigated Desktop session, app-server logs showed:

Shell snapshot successfully created: ~/.codex/shell_snapshots/<thread-id>.tmp-...

No Snapshot command timed out, Failed to create shell snapshot, validation failure, or finalize failure was logged for that thread.


Also, I investigated this issue with Codex, and using the Computer Use MCP, got it to fill out all of the fields. I did review all of the text, I'm not going to subject y'all to my slop.

extent analysis

TL;DR

The issue can be fixed by modifying the zsh snapshot export filter to preserve tied path parameters.

Guidance

  • The current filter only preserves simple export/declare -x/typeset -x lines, but zsh emits tied path parameters as export -T PATH path=( /opt/homebrew/bin /usr/bin /bin ... ), which is rejected as an invalid variable name.
  • To fix this, the filter needs to be updated to handle tied path parameters and normalize them into a sourceable scalar export PATH=... line.
  • The relevant source location for this fix is codex-rs/core/src/shell_snapshot.rs, specifically the zsh_snapshot_script() function.
  • The fix should ensure that the PATH variable is properly restored in the shell snapshot, allowing subsequent shell commands to resolve tools from the correct path.

Example

No code example is provided as the fix requires modifying the existing zsh_snapshot_script() function to handle tied path parameters.

Notes

The issue is specific to the Desktop app and does not occur when Codex is launched from a terminal. The fix should be applied to the codex-rs/core/src/shell_snapshot.rs file.

Recommendation

Apply a workaround by modifying the zsh_snapshot_script() function to handle tied path parameters, as this will allow the PATH variable to be properly restored in the shell snapshot.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

codex - 💡(How to fix) Fix Desktop app zsh snapshot export filter omits PATH, breaking Homebrew tools [2 comments, 2 participants]