Agent intermittently emits PowerShell-only syntax and fragile quoting
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_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:
- avoid
powershell.exe -Commandin 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 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/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 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.- Helpers in
.codex_tmpappear “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"orwindows.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 -cwith 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-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.
- 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-topleveland thenSet-Locationto 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.
6 Comments
Thanks for reporting the issue. When you run into problems like this, please use the
/feedbackcommand to upload the session details and include a short summary of the problem you experienced. These traces and failure modes are useful for our team who trains the codex models. With proper training, the models will continue to get better at handling tool calls, quoting, and other Windows-specific issues like those that you've mentioned in your bug report.Thanks, got it. I already submitted
/feedbackfrom the failing session and included a short description there. Session ID:019bccff-df08-77f1-8233-d4249d335e9c. I’m also pasting it here for convenience so it’s easy to locate the traces.If it would help, I can share additional context/materials: my
docs/INTERACTION_CONTRACT.mdandAGENTS.md, which document the Windows Native workaround I built (keep emitted lines minimal in CMD, and push all non-trivial logic into scripted helpers executed via pinned Windows PowerShell 5.1 usingpowershell.exe -File .codex_tmp\*.ps1). They also show the constraints I’m trying to enforce and the failure modes where the model still regresses (PowerShell-only syntax/cmdlets emitted into CMD, fragile quoting, and “mini-tool” overbuild instead of minimal probes).Let me know what would be most useful: the files themselves, a short summary of the key rules, or another
/feedbacksubmission from a different session that reproduces a specific failure mode.Thanks. Those details will generally be included in the session history, so they'll be included in the information you upload with the
/feedbackcommand.Update: I also submitted an in-app Feedback for this exact repro and included this thread ID:
019c169e-cff7-7ba2-a98e-f3bc1e699b84
Still reproducible on Windows native (cmd.exe /c) on codex-cli 0.92.x and 0.93.x.
What happened (log excerpt):
-> fatal: unable to resolve revision: restore"
After the failure, the agent “realized” the local rules and retried in a compliant way (single-token, no quotes):
Why this is notable:
My prompts always start with:
Read and follow AGENTS.md and docs/INTERACTION_CONTRACT.md.
Those guardrails explicitly forbid quotes in inline commands and require inline git grep to be single-token fixed-string only (multi-word patterns must switch to Scripted mode). In practice, the first attempt still violates the guardrails, hits the quoting/argv bug, and only then the agent corrects itself (reactive vs proactive compliance).
If you want, I can paste the exact guardrail snippet (a few lines) that forbids inline quotes and multi-word
git grep -e.Env: Microsoft Windows NT 10.0.17763.0 x64, terminal WezTerm, shell PowerShell 5.1, but command execution is via cmd.exe /c per logs.
Additional observation (may be related, Windows native cmd.exe /c):
This session shows the issue is not limited to
git grep. The agent repeatedly falls into forbidden inline patterns first, then corrects itself after failures (reactive vs proactive compliance), even with the prompt prefix “Read and follow AGENTS.md and docs/INTERACTION_CONTRACT.md.”Examples from the same run:
where powershell && where pwsh && where python ...(guardrails forbid&&).$path = ...) which fails as expected.powershell.exe -Command "Write-Output 123"printedWrite-Output 123instead of executing, and only-Command Write-Output 123worked. This looks like quoting/argv handling issues beyond git grep.If useful, I can paste a minimal log excerpt for each bullet.
Thanks. The behaviors you're describing are trained into the model. They're not under the control of the Codex harness. We'll share the feedback with the team responsible for training our codex models. If you see other model behavior that you'd like to report, please continue to use the
/feedbackcommand and upload your sessions. We use that information to inform improvements in the next model.I'm going to close this issue because there's nothing actionable for the Codex client itself at this time.