Windows tool shell contains both Path and PATH, breaking Start-Process with redirected stdio
Summary
Codex Desktop on Windows launches tool shells with both Path and PATH in the process environment. Windows environment variable lookup is case-insensitive, and this duplicate breaks PowerShell/.NET APIs that copy the environment into a case-insensitive dictionary.
Environment
- OS: Windows
- Codex Desktop package observed:
OpenAI.Codex_26.608.1337.0_x64__2p2nqsd0c76g0 - Workspace shell: Windows PowerShell
Reproduction
In a normal PowerShell session outside Codex:
[Environment]::GetEnvironmentVariables('Process').Keys | Where-Object { $_ -ieq 'PATH' }
Observed outside Codex:
Path
Inside a Codex tool shell, run the same command:
[Environment]::GetEnvironmentVariables('Process').Keys | Where-Object { $_ -ieq 'PATH' }
Observed inside Codex:
Path
PATH
The two values are identical except for Codex-added path entries.
Then attempt a normal background launch with redirected stdio:
$out = Join-Path (Get-Location) 'server.out.log'
$err = Join-Path (Get-Location) 'server.err.log'
Start-Process -FilePath node -ArgumentList 'server.mjs' -WorkingDirectory (Get-Location) -WindowStyle Hidden -RedirectStandardOutput $out -RedirectStandardError $err -PassThru
Observed error:
Start-Process : Item has already been added. Key in dictionary: 'Path' Key being added: 'PATH'
Expected behavior
On Windows, Codex should normalize environment variable keys case-insensitively before launching tool shells/commands. It should preserve the canonical Windows Path key and update that key when prepending Codex paths, rather than creating a separate PATH key.
Why this matters
This prevents Codex from using normal PowerShell Start-Process patterns for local dev servers with redirected stdout/stderr. Foreground node server.mjs works, but normal detached process launching from Codex fails because of the duplicate environment key.
Suggested fix
Before spawning Windows shell/tool commands, normalize env keys case-insensitively. For the path variable specifically, keep one canonical key:
function normalizeWindowsEnv(env: Record<string, string>) {
if (process.platform !== 'win32') return env;
const output: Record<string, string> = {};
const seen = new Map<string, string>();
for (const [key, value] of Object.entries(env)) {
const lower = key.toLowerCase();
if (lower === 'path') {
const canonical = seen.get('path') ?? 'Path';
output[canonical] = value;
seen.set('path', canonical);
continue;
}
if (!seen.has(lower)) {
seen.set(lower, key);
output[key] = value;
}
}
return output;
}
Then prepend Codex-specific path entries to the retained Path value instead of adding PATH.
2 Comments
Confirmed on Codex Desktop for Windows with app package
26.721.4979.0_x64andcodex-command-runner-0.146.0-alpha.3.1.exe.The process environment inside the Codex tool shell contains both
PathandPATH, while the Windows user and machine environments each contain only the normalPathkey. In this reproduction, the duplicate values were identical.A bounded test after fully restarting Codex produced:
Start-Processwithout redirected streams: succeeds and exits normally.-RedirectStandardOutputand-RedirectStandardError: fails withItem has already been added. Key in dictionary: 'Path' Key being added: 'PATH'.This appears to be injected by the Codex command-runner environment rather than by the user's Windows environment. No environment values or project data are included here.
I can confirm that this issue is still reproducible on my machine.
Environment
Control test outside Codex
In a normal Windows PowerShell window opened directly from Windows:
Pathenvironment variable exists.Start-Processtest succeeds with exit code0.