Windows/pwsh: apply_patch.bat breaks multiline patch arguments; direct codex.exe --codex-run-as-apply-patch succeeds with the same patch
What version of Codex CLI is running?
codex-cli 0.111.0
What subscription do you have?
plus
Which model were you using?
gpt-4.5
What platform is your computer?
Microsoft Windows NT 10.0.26200.0 x64
What terminal emulator and version are you using (if applicable)?
PowerShell 7.5.4
What issue are you seeing?
On Windows with PowerShell, apply_patch fails for valid multiline patch strings when invoked through
apply_patch.bat. The exact same patch succeeds when passed directly to codex.exe --codex-run-as-apply-patch, which
suggests the Windows wrapper is corrupting or truncating multiline arguments during forwarding. The observed error is:
Invalid patch: The last line of the patch must be '*** End Patch'.
What steps can reproduce the bug?
- Run Codex CLI on Windows in PowerShell.
- Check which executable is actually being used for
apply_patch:
``powershell``
Get-Command apply_patch
Get-Content -Raw (Get-Command apply_patch).Path
On my machine this resolves to a temporary wrapper like:
``text``
C:\Users\xxx\.codex\tmp\arg0\codex-arg0ARnQri\apply_patch.bat
and the wrapper contains:
``bat``
@echo off
"...\codex.exe" --codex-run-as-apply-patch %*
- Prepare a multiline patch string in PowerShell:
``powershell``
$patch = @"
*** Begin Patch
*** Add File: hello.txt
+hello
*** End Patch
"@
- Invoke the wrapper entrypoint:
``powershell``
apply_patch $patch
On my machine this fails with:
``text``
Invalid patch: The last line of the patch must be '*** End Patch'
- Invoke the underlying executable directly with the exact same
$patchvalue:
``powershell``
$codexExe = "...path extracted from the wrapper..."
& $codexExe --codex-run-as-apply-patch $patch
On my machine this succeeds and creates hello.txt.
What is the expected behavior?
apply_patch should be a reliable Windows entrypoint for multiline patch content.
If Codex uses a Windows shim or wrapper, it should preserve the patch argument exactly, including embedded newlines. Agents and workers that are instructed to edit files via apply_patch should not be blocked by shell-wrapper behavior.
What do you see instead?
A valid-looking multiline patch fails when sent through apply_patch.bat, but the identical patch succeeds when passed directly to codex.exe --codex-run-as-apply-patch.
That makes this look like a Windows wrapper / argument-forwarding bug, not a patch-format bug in the payload itself.
Additional information
I verified this locally on the same machine using the same patch content and saw different results depending only on the entrypoint:
apply_patch $patchfailedcodex.exe --codex-run-as-apply-patch $patchsucceeded
That isolates the behavior difference to the Windows wrapper path.
This matters because Codex agents are often instructed to edit files via apply_patch. On Windows/PowerShell, that becomes brittle if the wrapper forwards multiline arguments via %* and does not preserve them losslessly.
Potential fix directions:
- Bypass the
.batwrapper and expose a native executable entrypoint forapply_patchon Windows. - Pass patch content via stdin, a temp file, or another transport that does not depend on
%*preserving multiline payloads. - Change the Windows shim implementation so multiline arguments survive forwarding intact.
Additional information
Related issues:
4 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
I reviewed the suggested issues and do not think this report is a duplicate of them.
Access is deniedfailure on mapped/UNC Windows worktrees.This issue is narrower: on Windows PowerShell,
apply_patchresolves toapply_patch.bat, and the same multilinepatch fails via that wrapper but succeeds when passed directly to
codex.exe --codex-run-as-apply-patch. That pointsto a Windows wrapper / argument-forwarding problem rather than the issues above, so I am keeping this issue open.
I am experiencing the same underlying issue, but specifically within the Codex Desktop UWP App.
For additional context on why this bites users:
Because AI agents often prefer bash heredoc syntax (^Gpply_patch <<'PATCH'), when the UI interception fails, powershell receives bash syntax and crashes/timeouts. Even when the agent is instructed to use pipeline syntax (@'...'@ | apply_patch), the .bat wrapper mentioned in this issue destroys the multiline formatting.
Our current workaround:
We entirely replaced the .bat wrapper in our PATH with an ^Gpply_patch.ps1 script that correctly parses PowerShell Here-Strings (
| Out-String) and directly invokes codex.exe --codex-run-as-apply-patch. This proves that if the wrapper correctly forwarded multiline arguments, the underlying binary works perfectly.Independently reproduced this on the non-Store CLI build (
codex-cli 0.142.0-alpha.6/ Codex CLIv0.141.0) on Windows 11, PowerShell 7.6.2.Calling the generated shim:
Bypassing the
.batand callingcodex.exedirectly with the same$patchworks:Root cause as I see it: the shim is
cmd.exe's%*expansion collapses an argv that contains real\ninto a single physical line — the trailing*** End Patch(and intermediate lines) are dropped. This is structural tocmd.exeargument passing; switching the caller shell doesn't help (PowerShell, cmd, double-click all hit the same.bat → cmd → codex.exe argv[]path).Workarounds that worked for me:
$PROFILEwrapper that callscodex.exe --codex-run-as-apply-patch $patchdirectly, exported asSet-Alias apply_patch ....codex.exe ...directly and never go through the.bat.Suggested fixes for the shim (any one):
%*.%*to a temp file and pass the temp file path tocodex.exe..batwith a small PowerShell.ps1wrapper that callscodex.exewith the patch as a single argv string (PowerShell preserves the argv boundary correctly).