openai / openai/codex

Windows: hook commands with embedded quotes never execute (cmd /C outer-quote wrap in command_runner.rs) but hooks report Completed

Open
#38,168 3 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

bug CLI hooks windows-os
Dominant language
Rust
Stars
125k
Forks
19.5k
PR merge metrics
PR metrics pending

Description

Environment

  • codex-cli 0.147.0 on Windows 11 x64 (the spawn form below is also present on current main)
  • Project hooks in .codex/hooks.json using commandWindows

Summary

On Windows, build_command in codex-rs/hooks/src/engine/command_runner.rs spawns hook commands as cmd.exe /C "<command_line>" — the entire hook command line is wrapped in a literal pair of double quotes via raw_arg (shipped in #33926 to fix #32402).

That fix covers a leading quoted executable path ("C:\path with spaces\hook.cmd" notify), but it regresses any hook command that contains an embedded quoted segment — for example the natural way to write a PowerShell hook:

powershell.exe -NoProfile -NonInteractive -Command "<payload>"

cmd.exe mis-parses the outer-wrapped line, so the payload never executes. Depending on the exact token stream Codex still prints hook: <Event> Completed, making the failure completely silent (this is very likely the mechanism behind #33564 as well).

Minimal repro

  1. Configure and trust a project UserPromptSubmit hook with:
"commandWindows": "powershell.exe -NoProfile -NonInteractive -Command \"Set-Content -Path '%USERPROFILE%\\hook-canary.txt' -Value ran\""
  1. Trigger the event.

  2. Codex reports hook: UserPromptSubmit Completed, but hook-canary.txt is never created. No spawn result, exit code, stdout, or stderr is persisted anywhere I could find.

Exact spawn-form repro (outside Codex)

This is exactly what Codex executes since #33926 (cmd.exe /C + raw_arg("\"{command_line}\"")):

cmd.exe /C "powershell.exe -NoProfile -NonInteractive -Command "Set-Content -Path 'D:\Temp\canary.txt' -Value ran""

Result: exit 1, 系统找不到指定的路径。 (path-not-found from cmd's mis-parse), file never created.

Control cases that both work correctly:

  • direct spawn: powershell.exe -NoProfile -NonInteractive -Command "Set-Content -Path 'D:\Temp\canary.txt' -Value ran" → exit 0, file created
  • cmd.exe /C without the outer quote wrap: cmd.exe /C powershell.exe -NoProfile -NonInteractive -Command "Set-Content -Path 'D:\Temp\canary.txt' -Value ran" → exit 0, file created

So the defect is specifically the outer-quote wrapping, not the command itself and not PowerShell.

Expected behavior

  1. Pass the hook command line to cmd.exe /C verbatim (via raw_arg, without adding an outer quote pair), or otherwise preserve embedded quotes correctly, so commands like the PowerShell form above execute as written.
  2. When the hook process fails to launch or exits non-zero, do not report Completed; persist the spawn result, exit code, stdout, and stderr so silent no-ops are diagnosable (also requested in #33564).

Workaround

Use a quote-free, space-free command line and move all real logic into a batch file:

"commandWindows": "cmd.exe /c C:\\path\\to\\hook-wrapper.cmd"

Verified working end-to-end on codex-cli 0.147.0 (hook output JSON is parsed and additionalContext attaches correctly once the command actually executes).

Refs

  • #32402 — original quoted-path failure (closed by #33926)
  • #33926 — introduced the outer-quote wrap that causes this embedded-quote failure
  • #33564 — Desktop: trusted hook "completes" but handler never reaches script entry; likely the same mechanism

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in codex-rs/hooks/src/engine/command_runner.rs at build_command, then run the exact Windows cmd.exe /C repro and compare it with the two control cases. Done means embedded-quote hook commands execute correctly, and launch failures or non-zero exits are not reported as Completed while their diagnostics are persisted.

Written by the indexing model from the issue text.

Assessment

Tech stack
powershell, rust
Domain
cli, tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.