Windows: hook commands with embedded quotes never execute (cmd /C outer-quote wrap in command_runner.rs) but hooks report Completed
Nobody has claimed this yet.
- 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.jsonusingcommandWindows
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
- Configure and trust a project
UserPromptSubmithook with:
"commandWindows": "powershell.exe -NoProfile -NonInteractive -Command \"Set-Content -Path '%USERPROFILE%\\hook-canary.txt' -Value ran\""
-
Trigger the event.
-
Codex reports
hook: UserPromptSubmit Completed, buthook-canary.txtis 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 /Cwithout 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
- Pass the hook command line to
cmd.exe /Cverbatim (viaraw_arg, without adding an outer quote pair), or otherwise preserve embedded quotes correctly, so commands like the PowerShell form above execute as written. - 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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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