This troubleshooting session is absolutely worth documenting in full, because it managed to step on almost every easiest-to-hit category of pitfalls for desktop AI tools on Windows: custom APIs, WSL, Windows native, PowerShell, PATH, shims, Store-version bundled binaries, and the classic “it looks like it appeared out of nowhere, but in reality an old latent issue got re-triggered.”
Let’s state the conclusion up front:
What actually made Codex Desktop completely unable to run commands on Windows native was not WSL, not the PowerShell profile, and not a mismatch between the desktop and npm versions, but a batch shim hidden at C:\\Users\\1\\AppData\\Local\\Programs\\Python\\Python313\\Scripts\\pwsh.cmd. When Codex’s Windows command executor starts this .cmd wrapper with arguments, it immediately errors with: batch file arguments are invalid, so every command dies before it even executes.
1. Where the incident started: it looked like “switching to WSL broke it”
At the beginning, the surface symptoms actually had two layers:
- After switching both the Agent and Integrated terminal in Codex settings to WSL, the desktop app started reconnecting nonstop, erroring with:
Reconnecting... 1/5
...
stream disconnected before completion: error sending request for url (https://wuju.de5.net/v1/responses)
- But the user explicitly said: don’t fix WSL first—fix the original Windows native issue, because native was broken first, and that’s why they switched to WSL.
This step matters, because it separates two problems:
- The WSL path looks more like a network/proxy/WSL environment access-to-custom-endpoint issue.
- The Windows native path is that the local command executor itself was already broken.
If you don’t separate them first, you’ll keep misdiagnosing back and forth between two independent failures.
2. First minimal reproduction: not “one command is broken,” but “all commands die before execution”
To confirm whether this was Git, PowerShell, or Codex itself, we ran minimal command tests:
Write-Output hiGet-Locationgit status -sbcmd.exe /c echo hi
The results were perfectly consistent—everything failed with the same error:
execution error: Io(Error { kind: InvalidInput, message: "batch file arguments are invalid" })
This is extremely valuable because it directly indicates:
- Not a Git-specific issue.
- Not a working-directory-specific issue.
- Not some script in the PowerShell profile breaking specific commands.
- Not even
cmd.exe /c(a “bypass PowerShell” path) can escape.
So the fault is in the “command launch layer,” not the command itself.
3. Second misleading point: the integrated terminal is clearly fine—why does Codex say it can’t?
At the time, the integrated terminal screenshot in the thread looked normal: the prompt appeared, and you could see:
PowerShell 7.5.4
PS C:\Users\1\0.0.90_0>
This easily leads to the wrong conclusion:
- If the terminal opens, PowerShell itself must be fine.
- Then it’s probably a bug in Codex’s built-in runner.
That’s only half right.
PowerShell itself wasn’t broken, but in Codex Desktop, “the terminal can display” does not mean “the agent command executor can successfully start a shell with arguments and run commands.” Those are different pipelines.
This was the first major takeaway:
A normal interactive integrated terminal does not prove the agent’s shell_command chain is healthy.
4. Third misdiagnosis: we briefly suspected the Store build bundled an old backend
Next we found something very suspicious:
- The Microsoft Store desktop resources bundled a CLI/runner version:
0.112.0-alpha.3 - The machine’s globally installed npm
@openai/codexwas already0.113.0
This looks like a root cause because “new desktop shell, old embedded runtime” can absolutely cause bizarre behavior.
So we did a fairly hardcore but very valuable verification:
- Copied a writable desktop app copy out of the Store build.
- Replaced
codex.exe,codex-command-runner.exe, etc. with the npm0.113.0binaries. - Launched the patched desktop, then reproduced in a new thread.
If version mismatch were the cause, the patched build should recover.
Result: no recovery at all.
Even the simplest git status -sb in a new thread still failed the same way:
batch file arguments are invalid
This step was crucial because it eliminated a hypothesis that really looked like the root cause.
The conclusion became:
- The
0.112.0-alpha.3vs0.113.0mismatch is, at most, noise—or a separate issue worth tracking. - But it is not the root cause of this native shell crash.
Second major takeaway:
There can be many “suspicious points” that explain the symptoms, but if a patch experiment doesn’t remove the symptom, it isn’t the root cause.
5. More elimination: the PowerShell profile is loud, but not the fatal point this time
In the middle, we also saw PowerShell profile errors—for example, after .wt_proxy_config.json was read as null, profile logic like Add-Member / $cfg.enabled blew up.
These errors should be fixed because they pollute the terminal startup experience and make people suspect shell initialization issues.
But there’s a key judgment call here:
If the real root cause were the profile, at least some command paths should bypass it, or the error shape should look more like a PowerShell script exception—not every command uniformly failing at the launcher layer with batch file arguments are invalid.
Later evidence confirmed: the profile was not the main reason the native executor was completely dead.
6. The real breakthrough: a very weird pwsh.cmd was discovered
What finally nailed the issue was finding this file on the machine:
C:\Users\1\AppData\Local\Programs\Python\Python313\Scripts\pwsh.cmd
Its content was just two lines:
@echo off
"C:\Program Files\PowerShell\7\pwsh.exe" %*
This looks like a “helpful shim,” meant to wrap pwsh and forward to the real PowerShell 7.
But for Codex Desktop’s Windows executor, it’s poison:
- It isn’t
pwsh.exe; it’s a.cmdbatch wrapper. - When Codex’s command executor hits it and calls it with arguments on a certain path, it directly triggers:
batch file arguments are invalid
In other words: the command dies at the .cmd layer before it ever reaches pwsh.exe.
This perfectly explains why all of these died:
Write-Output hiGet-Locationgit status -sbcmd.exe /c echo hi
Because what’s broken is the outermost shell bootstrap, not the target command.
7. The key evidence chain: this pit wasn’t created today
The most interesting and counterintuitive part is here.
User perception: “it suddenly appeared about three hours ago; it wasn’t broken before.”
But logs show this issue predates “today’s sudden appearance”:
Evidence 1: the pwsh.cmd shim was written on 2026-02-02 18:52:53 (local time)
In codex-tui.log, you can see a clear write action—writing pwsh.cmd directly into Python’s Scripts directory.
Evidence 2: the same class of error already appeared as early as 2026-02-03 15:02:40 (local time)
Starting Feb 3, the logs already had many instances of:
exec error: batch file arguments are invalid
There were even explicit records of attempts to invoke this shim.
Evidence 3: the current failure re-exposed around 2026-03-11 04:11, and the 04:33 reproduction test hit it reliably
So today isn’t “this bad configuration was created today,” but rather “an old latent issue got hit again, and it happened to match the current execution path.”
8. So why did it feel like it “suddenly broke three hours ago”?
This is the part most worth clarifying.
The more accurate statement is:
The bad configuration wasn’t created three hours ago; rather, around three hours ago Codex Desktop started taking an execution path that hits pwsh.cmd again.
Based on the evidence, the most reasonable explanation is a combination like this—not “the software secretly updated”:
- The
pwsh.cmdlandmine had been planted long ago. - It already caused similar errors in early February, but it didn’t always surface the same way.
- This time, the user switched back into Windows native + PowerShell-related paths to troubleshoot.
- Meanwhile, the desktop/back-end process reloaded persisted environment state and resolved
pwshvia PATH again. - This time resolution hit the
.cmdshim, and the issue fully exploded again.
In other words, this kind of failure can “suddenly appear” without any software update.
Any of the following can re-activate old latent issues:
- Desktop app restart
- Background agent process restart
- Switching from WSL back to Windows native
- Changing settings that re-initialize the shell
- A new thread that stops reusing old environment and re-reads persisted PATH
To be honest:
I can confirm the “old latent issue + new trigger” structure, but I can’t prove from existing logs alone which exact moment/action triggered it.
But I can be very sure it’s not “some unknown new bad config created today.”
9. Final fix actions
The fix that restored Windows native was simple—but it had to be precise:
Action 1: move the shim out of the way
Rename:
C:\Users\1\AppData\Local\Programs\Python\Python313\Scripts\pwsh.cmd
to:
C:\Users\1\AppData\Local\Programs\Python\Python313\Scripts\pwsh.cmd.disabled-by-codex
Action 2: put PowerShell 7 ahead of it in the user PATH
Explicitly place:
C:\Program Files\PowerShell\7\
at the front of the user Path, to prevent future resolution from hitting other shims first.
Action 3: broadcast the environment variable change
Not only edit the registry, but also explicitly send WM_SETTINGCHANGE / Environment so new processes pick up the updated environment ASAP.
Action 4: the patched startup script also proactively prepends PowerShell 7
So even if something later changes PATH elsewhere, this startup chain is less likely to be polluted.
After the fix, the user confirmed: it finally works normally again.
10. What detours did we take, and why were they still worth it?
It looks like a lot of circling, but every detour narrowed the problem space:
Detour 1: getting misled by the WSL network error
Value: confirmed WSL issues and native issues were not the same failure.
Detour 2: suspecting the PowerShell profile
Value: separated “terminal init noise” from “fatal command executor failure.”
Detour 3: suspecting the desktop bundled backend lagging behind
Value: the patched app experiment directly ruled out “pure version mismatch.”
Detour 4: trying different command entry points
For example, running:
Write-Output hicmd.exe /c echo hipowershell -NoProfile -Command ...& git.exe status -sb
Value: proved every path failed at the same pre-execution layer, not a shell-specific bug.
So these detours weren’t wasted; they gradually compressed the problem from “it could be anywhere” to “it can only be a very low-level Windows shell bootstrap / PATH / shim issue.”
11. The most practical lessons from this incident
Lesson 1: in desktop AI tools, “the terminal displays normally” doesn’t mean the agent executor is healthy
The UI terminal and the background command execution chain are different things.
Lesson 2: shortest-possible command tests are extremely valuable
Tests like Write-Output hi, Get-Location, cmd.exe /c echo hi are far more effective than starting with complex commands.
Lesson 3: version differences are not automatically root cause
If replacing binaries changes nothing, version differences are at most a companion symptom.
Lesson 4: shims on Windows are extremely sneaky
Especially .cmd, .bat, Python Scripts directories, and WindowsApps proxy stubs—usually harmless-looking, but if a program resolves things differently than you assume, the failure can be absurd.
Lesson 5: “it suddenly broke today” doesn’t necessarily mean “the root cause appeared today”
Many system-level issues really have this structure:
- the hazard existed long ago
- it wasn’t hit for a long time
- after a process restart/mode switch/environment reload, it suddenly explodes
Lesson 6: the log timeline is critically important
If you only look at the present, it’s easy to misread “triggered today” as “created today.”
12. The most essential one-sentence conclusion
This wasn’t simply “Codex broke,” but a classic Windows environment contamination problem: a long-planted pwsh.cmd shim got hit again when re-entering the Windows native shell path, and it blew up Codex Desktop’s command executor as a whole.
If you run into something similar in the future:
- all commands fail uniformly
- errors are short and unrelated to command content
- the integrated terminal opens but the agent can’t run
- different command entry points all fail the same way
…then stop staring at Git, the repo, the profile, or even the app version. Check first:
where.exe pwsh- PATH order
- whether there’s a same-named
.cmd/.batshim - whether WindowsApps / Python Scripts / custom launcher directories hide a wrapper
Once the root cause is found, the fix is usually small.
The hard part is: digging the real landmine out of a pile of very convincing noise.