What version of Codex is running?
codex-cli 0.87.0
What subscription do you have?
Plus
Which model were you using?
gpt-5.2 high
What platform is your computer?
Microsoft Windows NT 10.0.17763.0 x64
What terminal emulator and version are you using (if applicable)?
WezTerm
What issue are you seeing?
On Windows Native, my Codex CLI sessions consistently show that commands are executed via a cmd.exe /c "<line>" wrapper. The agent intermittently generates commands and quoting patterns that assume a PowerShell execution context, which leads to failures (PowerShell cmdlets in CMD, broken quoted phrases, CMD metacharacter issues, CWD drift). I can work around many cases by forcing a scripted helper approach (powershell.exe -File .codex_tmp\*.ps1), but this is brittle and sometimes regresses, and it pushes the agent into writing large “mini-tools” instead of completing the task.
Workaround details (what .codex_tmp and “Scripted mode” mean here)
I use a repo-local workaround to make Windows Native execution more deterministic:
-
.codex_tmp is a folder inside the repository that I use to store short-lived helper PowerShell scripts for probes and checks.
-
“Scripted mode” (in this context) means: the emitted <line> (which still runs through cmd.exe /c) does only one thing, it launches pinned Windows PowerShell with -File .codex_tmp\<helper>.ps1 plus simple arguments, and all complex logic lives inside that .ps1.
-
This behavior is documented in my repo in AGENTS.md and in docs/INTERACTION_CONTRACT.md (which AGENTS.md references). The contract includes “do / don’t” examples and constraints like:
- avoid
powershell.exe -Command in emitted lines,
- keep emitted CMD lines minimal (no complex quoting),
- avoid CMD metacharacters in emitted lines,
- prefer git-native queries where possible,
- push anything non-trivial into a helper
.ps1.
Even with this workaround, the agent sometimes regresses into emitting PowerShell-only constructs in CMD, fragile quoted phrases, or building oversized helper “mini-projects” in .codex_tmp.
What consistently works (and why)
-
Scripted mode via pinned Windows PowerShell 5.1 and -File
Stable pattern: the emitted <line> is minimal CMD, it only invokes a pinned powershell.exe and only -File .codex_tmp\*.ps1. All complex logic lives inside the temporary .ps1.
Why it works: it avoids multi-layer quoting in cmd.exe /c "<line>", and argument handling occurs inside PowerShell where quoting is controllable.
-
“Simple in CMD, complex in .ps1”
Stable pattern: keep CMD to simple commands like type and simple git grep (no complex quoting), and use scripted helpers for ranged file views, parsing, structured checks.
What consistently fails (symptoms)
-
Shell confusion: PowerShell syntax emitted in CMD
Agent emits PowerShell cmdlets/syntax in <line>, but the runner executes with CMD, so it fails predictably.
-
Quoted multi-word arguments do not survive cmd.exe /c "<line>" reliably
Examples of symptom class:
findstr /n "Fail if tracked text files" ... degrades into attempts to open if, tracked, files as separate files.
git grep -F "not currently enforced" ... turns into something like “unable to resolve revision: currently”, because the phrase gets split and interpreted as separate positional arguments.
Key point: this is not a git/findstr bug, it is fragile tokenization/quoting through the wrapper.
-
CMD metacharacters and inline interpreters blow up
<, >, <<, |, &, ^, parentheses, etc. are treated as CMD operators. Inline patterns like python -c with embedded quoting or heredoc-like tokens fail.
-
CWD drift breaks relative paths
Sometimes the runner is no longer at repo root, and .codex_tmp\... helpers are not found even though they exist.
Main new failure mode not fixed by quoting rules
The agent sometimes starts building “mini-projects” in .codex_tmp (one-off tools, report generators, large repo scanners), then the session degrades into debugging that tool (StrictMode, .Count, return types, etc.). This is separate from CMD quoting and is not resolved just by “ban -Command / use -File”.
In other words: we can beat quoting hell with -File, but we still lose to “tool-building drift” where the agent over-engineers helpers and then debugs them.
What steps can reproduce the bug?
- On Windows Native, run a task that requires searching for a multi-word phrase or running a command with special characters.
- Observe the emitted command is executed via
cmd.exe /c "<line>".
- Observe one or more of:
- PowerShell cmdlets emitted in
<line> and failing.
- Quoted phrase split into multiple argv tokens (findstr/git grep symptoms).
- CMD metacharacter interpretation breaking one-liners.
- CWD drift breaking
.codex_tmp\... relative paths.
Notes about typical failure signatures
findstr /n "Fail if tracked text files" ... degenerates into attempts to open if, tracked, files as separate files.
git grep -F "not currently enforced" ... turns into “unable to resolve revision: currently”.
python -c ... one-liners containing < / << / nested quoting produce CMD parse failures like Unexpected appearance: << and/or Python SyntaxError.
- Helpers in
.codex_tmp appear “missing” if the runner is not in repo root.
What is the expected behavior?
- On Windows Native, the agent should reliably understand the actual execution shell and generate commands compatible with it.
- If the runner uses
cmd.exe /c, the agent should not emit PowerShell-only cmdlets/syntax in the single-line command.
- Quoted multi-word arguments should not be split or re-tokenized unexpectedly.
- If Scripted mode is the recommended approach for complex operations, the agent should consistently select it and keep helpers minimal and robust.
Additional information
Diagnoses (where it seems to go wrong)
-
Scripted-mode triggers are not applied consistently
Even if guidelines exist (“if in doubt, use scripted”), the agent still tries “cheap” approaches (findstr, quoted phrases, python one-liners) and regresses on tasks that include spaces/metacharacters.
-
Missing “safe primitives”
When the agent lacks a known-safe primitive (grep with line numbers, byte-level checks, safe argv building), it either:
- tries CMD (fails), or
- writes a big helper (then fails inside PowerShell or wastes iterations).
- Working directory invariants are not enforced end-to-end
Even if “work in repo root” is intended, CWD drifts and relative paths break.
Requested improvements (two alternative solutions)
Option A (preferred): allow selecting the execution shell on Windows Native
Provide a config option to select the default shell (e.g., PowerShell) for Windows Native runs, so the agent can safely emit PowerShell-native commands without being wrapped by CMD tokenization.
Example (illustrative, naming is up to you):
shell = "powershell" or windows.default_shell = "powershell"
- Support for pinned PS 5.1 path if needed.
This would remove the root cause: CMD parsing and metacharacter semantics.
Option B: make the agent shell-aware and enforce CMD-safe emission
If cmd.exe /c remains the execution wrapper, then the system should enforce:
- No PowerShell cmdlets/syntax in emitted
<line>.
- No quoted multi-word arguments in
<line> unless guaranteed stable tokenization is implemented.
- Hard-stop avoidance of CMD metacharacters in
<line>.
- Automatic escalation to scripted helpers when commands require spaces/metacharacters/complex parsing.
- A stable CWD strategy (see below).
Practical implementation suggestions (based on observed failure patterns)
- “Red zone” hard-stop rules for CMD emission
If the runner is cmd.exe /c, then the emitted <line> should never contain:
- PowerShell cmdlets/syntax (cmdlets,
;, pipelines intended for PS, etc.)
- CMD metacharacters:
<, >, <<, |, &, ^, (, )
- Inline interpreter one-liners for non-trivial logic (especially
python -c with nested quoting)
- Multi-word quoted phrases that must remain a single argv token
- Provide 2–3 official helper primitives (so the agent stops reinventing)
For example:
grep-with-line-numbers helper implemented in PowerShell (Select-String + line numbers) instead of findstr in CMD.
byte-check helper for BOM/NUL/CRLF checks.
safe git argv wrapper helper that calls git with an argv array from PowerShell, avoiding quoting entirely.
- Stabilize CWD inside every helper script
At the top of each helper .ps1, resolve repo root and Set-Location inside PowerShell:
git rev-parse --show-toplevel and then Set-Location to it.
This makes helpers independent from runner CWD drift.
- Limit helper complexity and prevent “mini-project drift”
Enforce:
- Helpers must be short “probes” only unless explicitly requested.
- No report generation or large scanners by default.
- Keep helper scope minimal and deterministic.
What version of Codex is running?
codex-cli 0.87.0
What subscription do you have?
Plus
Which model were you using?
gpt-5.2 high
What platform is your computer?
Microsoft Windows NT 10.0.17763.0 x64
What terminal emulator and version are you using (if applicable)?
WezTerm
What issue are you seeing?
On Windows Native, my Codex CLI sessions consistently show that commands are executed via a
cmd.exe /c "<line>"wrapper. The agent intermittently generates commands and quoting patterns that assume a PowerShell execution context, which leads to failures (PowerShell cmdlets in CMD, broken quoted phrases, CMD metacharacter issues, CWD drift). I can work around many cases by forcing a scripted helper approach (powershell.exe -File .codex_tmp\*.ps1), but this is brittle and sometimes regresses, and it pushes the agent into writing large “mini-tools” instead of completing the task.Workaround details (what
.codex_tmpand “Scripted mode” mean here)I use a repo-local workaround to make Windows Native execution more deterministic:
.codex_tmpis a folder inside the repository that I use to store short-lived helper PowerShell scripts for probes and checks.“Scripted mode” (in this context) means: the emitted
<line>(which still runs throughcmd.exe /c) does only one thing, it launches pinned Windows PowerShell with-File .codex_tmp\<helper>.ps1plus simple arguments, and all complex logic lives inside that.ps1.This behavior is documented in my repo in
AGENTS.mdand indocs/INTERACTION_CONTRACT.md(whichAGENTS.mdreferences). The contract includes “do / don’t” examples and constraints like:powershell.exe -Commandin emitted lines,.ps1.Even with this workaround, the agent sometimes regresses into emitting PowerShell-only constructs in CMD, fragile quoted phrases, or building oversized helper “mini-projects” in
.codex_tmp.What consistently works (and why)
Scripted mode via pinned Windows PowerShell 5.1 and
-FileStable pattern: the emitted
<line>is minimal CMD, it only invokes a pinnedpowershell.exeand only-File .codex_tmp\*.ps1. All complex logic lives inside the temporary.ps1.Why it works: it avoids multi-layer quoting in
cmd.exe /c "<line>", and argument handling occurs inside PowerShell where quoting is controllable.“Simple in CMD, complex in .ps1”
Stable pattern: keep CMD to simple commands like
typeand simplegit grep(no complex quoting), and use scripted helpers for ranged file views, parsing, structured checks.What consistently fails (symptoms)
Shell confusion: PowerShell syntax emitted in CMD
Agent emits PowerShell cmdlets/syntax in
<line>, but the runner executes with CMD, so it fails predictably.Quoted multi-word arguments do not survive
cmd.exe /c "<line>"reliablyExamples of symptom class:
findstr /n "Fail if tracked text files" ...degrades into attempts to openif,tracked,filesas separate files.git grep -F "not currently enforced" ...turns into something like “unable to resolve revision: currently”, because the phrase gets split and interpreted as separate positional arguments.Key point: this is not a
git/findstrbug, it is fragile tokenization/quoting through the wrapper.CMD metacharacters and inline interpreters blow up
<,>,<<,|,&,^, parentheses, etc. are treated as CMD operators. Inline patterns likepython -cwith embedded quoting or heredoc-like tokens fail.CWD drift breaks relative paths
Sometimes the runner is no longer at repo root, and
.codex_tmp\...helpers are not found even though they exist.Main new failure mode not fixed by quoting rules
The agent sometimes starts building “mini-projects” in
.codex_tmp(one-off tools, report generators, large repo scanners), then the session degrades into debugging that tool (StrictMode,.Count, return types, etc.). This is separate from CMD quoting and is not resolved just by “ban-Command/ use-File”.In other words: we can beat quoting hell with
-File, but we still lose to “tool-building drift” where the agent over-engineers helpers and then debugs them.What steps can reproduce the bug?
cmd.exe /c "<line>".<line>and failing..codex_tmp\...relative paths.Notes about typical failure signatures
findstr /n "Fail if tracked text files" ...degenerates into attempts to openif,tracked,filesas separate files.git grep -F "not currently enforced" ...turns into “unable to resolve revision: currently”.python -c ...one-liners containing</<</ nested quoting produce CMD parse failures likeUnexpected appearance: <<and/or PythonSyntaxError..codex_tmpappear “missing” if the runner is not in repo root.What is the expected behavior?
cmd.exe /c, the agent should not emit PowerShell-only cmdlets/syntax in the single-line command.Additional information
Diagnoses (where it seems to go wrong)
Scripted-mode triggers are not applied consistently
Even if guidelines exist (“if in doubt, use scripted”), the agent still tries “cheap” approaches (findstr, quoted phrases, python one-liners) and regresses on tasks that include spaces/metacharacters.
Missing “safe primitives”
When the agent lacks a known-safe primitive (grep with line numbers, byte-level checks, safe argv building), it either:
Even if “work in repo root” is intended, CWD drifts and relative paths break.
Requested improvements (two alternative solutions)
Option A (preferred): allow selecting the execution shell on Windows Native
Provide a config option to select the default shell (e.g., PowerShell) for Windows Native runs, so the agent can safely emit PowerShell-native commands without being wrapped by CMD tokenization.
Example (illustrative, naming is up to you):
shell = "powershell"orwindows.default_shell = "powershell"This would remove the root cause: CMD parsing and metacharacter semantics.
Option B: make the agent shell-aware and enforce CMD-safe emission
If
cmd.exe /cremains the execution wrapper, then the system should enforce:<line>.<line>unless guaranteed stable tokenization is implemented.<line>.Practical implementation suggestions (based on observed failure patterns)
If the runner is
cmd.exe /c, then the emitted<line>should never contain:;, pipelines intended for PS, etc.)<,>,<<,|,&,^,(,)python -cwith nested quoting)For example:
grep-with-line-numbershelper implemented in PowerShell (Select-String+ line numbers) instead offindstrin CMD.byte-checkhelper for BOM/NUL/CRLF checks.safe git argv wrapperhelper that callsgitwith an argv array from PowerShell, avoiding quoting entirely.At the top of each helper
.ps1, resolve repo root andSet-Locationinside PowerShell:git rev-parse --show-topleveland thenSet-Locationto it.This makes helpers independent from runner CWD drift.
Enforce: