Windows: hook commands containing a quoted path break under cmd.exe (backslash-escaped quotes)
Bug
codex-rs/hooks/src/engine/command_runner.rs spawns a hook command on Windows via cmd.exe /C <command>, passing the entire hook command string as a single argv element to Command::new(comspec).arg("/C").arg(&handler.command).
Rust's Windows argv escaping (std::process, following CommandLineToArgvW rules) rewrites every embedded " in that argument as \". cmd.exe does not understand \". So a perfectly ordinary hook command that quotes its executable path (the documented way to write a path containing spaces):
command = '"C:\Users\me\AppData\Local\Programs\SomeApp\somebinary.exe" notify'
reaches cmd.exe as the literal token \"C:\...\somebinary.exe\" and fails:
'\"C:\Users\me\AppData\Local\Programs\SomeApp\somebinary.exe\"' is not recognized as an internal or external command
EXIT CODE: 1
Codex surfaces this as SessionStart hook (failed) — hook exited with code 1. Any hook whose command quotes its executable path — i.e. any hook on a path containing a space — is unrunnable on Windows.
Repro
- Install any hook on Windows via
~/.codex/config.tomlwhosecommandvalue is a quoted absolute path (required whenever the install path contains a space, e.g. anything under%LOCALAPPDATA%\Programs\...with a space in the app name, orC:\Program Files\...). - Trigger the hook event.
- Observe the hook fails with exit code 1 and the
\"...\"malformed-token error above.
Suggested fix
Use std::os::windows::process::CommandExt::raw_arg() for the cmd.exe branch instead of .arg(), so the command string is passed through to cmd /C verbatim rather than being re-escaped. This is exactly the case raw_arg exists for.
Workaround we shipped downstream
We work around this in our own tool by emitting a quote-free, space-free Windows command string (resolving the path via cmd.exe's for %~sI short-path trick) so the hook command never needs a literal " — see delllusional/DontSpeak#23 for context. That workaround only fixes hooks we control; any other hook with a quoted/spaced path is still affected.
Refs: codex-rs/hooks/src/engine/command_runner.rs (build_command / default_shell_command).