Windows sandbox: restricted token cannot enumerate or execute under the user profile, so pwsh/python/gh silently "do not exist"
What version of Codex CLI is running? codex-cli 0.146.1 (@openai/codex 0.146.1, codex-win32-x64)
What subscription do you have? ChatGPT (auth_mode = chatgpt)
Which model were you using? gpt-5.6-sol
What platform is your computer? Microsoft Windows NT 10.0.26200.9168 x64
What terminal emulator? Reproduced from Git Bash (MSYS2) and cmd.exe; not terminal-specific.
Codex doctor report: 17 ok · 1 idle · 1 notes · 0 warn · 0 fail — auth, connectivity and model access are all healthy. The failure is entirely in the sandbox command runner.
---
What issue are you seeing?
On this machine the Windows sandbox's restricted token can stat paths under C:\Users\<user>\ but cannot enumerate directories or execute binaries there. Sandboxed codex exec is consequently unable to run any tool installed under the user profile — which on a normal Windows dev box is most of them.
It surfaces as two unrelated-looking symptoms with one cause.
Symptom 1 — total CreateProcessAsUserW failed: 5 when pwsh is an MSIX App Execution Alias
windows sandbox: runner failed during SpawnChild: CreateProcessAsUserW failed: 5 (Access is denied.)
| cwd=C:\Users\<user>\dev\<repo>
| cmd=C:\Users\<user>\AppData\Local\Microsoft\WindowsApps\pwsh.exe -NoProfile -Command "..."
| env_u16_len=5450 | si_flags=256 | creation_flags=525312 (Windows error 5)
The cmd= path is under the user profile. …\AppData\Local\Microsoft\WindowsApps\pwsh.exe is an App Execution Alias — a reparse point into C:\Program Files\WindowsApps\Microsoft.PowerShell_7.6.4.0_x64__8wekyb3d8bbwe\pwsh.exe — and the sandbox token cannot execute it. Every command fails before it runs, under both -s read-only and -s workspace-write.
This is a common configuration rather than an exotic one: winget install --id Microsoft.PowerShell installs the msix variant, and that is the only installer in the manifest.
> winget show --id Microsoft.PowerShell --exact
Version: 7.6.4.0
Installer Type: msix
Installer Url: .../PowerShell-7.6.4.msixbundle
So anyone who installed PowerShell 7 via winget and never separately ran the MSI has pwsh on PATH as an alias only, with C:\Program Files\PowerShell\7\pwsh.exe absent. winget install --installer-type msi --force cannot help — it returns No applicable installer found, because the manifest has no MSI.
Workaround for this half: remove WindowsApps from the PATH the codex process itself sees. Shell discovery then falls through its candidate list (pwsh → pwsh.exe → powershell → powershell.exe) to Windows PowerShell 5.1 at C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe, which is machine-wide, and commands spawn correctly.
Symptom 2 — with a machine-wide shell, every user-profile tool reports "not recognized"
After that workaround the sandbox runs commands, but only machine-wide ones. git (at C:\Program Files\Git) works; python and gh do not:
gh : The term 'gh' is not recognized as the name of a cmdlet, function, script file, or operable program.
python : The term 'python' is not recognized as the name of a cmdlet, function, script file, or operable program.
This is not a PATH problem. I initially assumed it was and was wrong. Dumping $env:PATH from inside the sandbox shows the inherited PATH arrives intact, including both directories:
C:\Users\<user>\.codex\tmp\arg0\codex-arg0CGD0Ky
C:\Users\<user>\AppData\Roaming\npm\...\codex-win32-x64\vendor\...\codex-path
C:\Program Files\Git\mingw64\bin
...
C:\Users\<user>\AppData\Local\Programs\Python\Python312 <-- present
...
C:\Users\<user>\AppData\Local\Microsoft\WinGet\Links <-- present
shell_environment_policy also works correctly — arbitrary variables set via -c shell_environment_policy.set.FOO=bar arrive in the child exactly as configured. Neither mechanism is at fault.
The actual cause, probed directly
Run inside the sandbox (-s workspace-write, machine-wide PowerShell):
$p = "C:\Users\<user>\AppData\Local\Programs\Python\Python312\python.exe"
$g = "C:\Program Files\Git\cmd\git.exe"
Test-Path -LiteralPath $p # -> True
Test-Path -LiteralPath $g # -> True
Get-ChildItem -LiteralPath (Split-Path $p) # -> UnauthorizedAccessException
& $p -c "print(42)" # -> ApplicationFailedException
The token can stat the user-profile executable, but cannot enumerate its directory and cannot execute it. The machine-wide binary is fine. That single fact produces both symptoms: pwsh fails to spawn because the alias is in the profile, and python/gh are "not found" because PowerShell's command discovery cannot enumerate the PATH directories holding them.
Writes to the workspace itself succeed under -s workspace-write even though the workspace is also under C:\Users\<user>\, so this is not a blanket profile denial — execute and enumerate are denied where write is allowed.
-s danger-full-access is unaffected, since it does not use the sandbox runner:
> codex exec -s danger-full-access 'run: git rev-parse --short HEAD; gh --version; python -c "print(1+1)"'
90756b1
gh version 2.95.0 (2026-06-17)
2
What steps can reproduce the bug?
- Windows 11. Install PowerShell 7 with
winget install --id Microsoft.PowerShell(yields msix). ConfirmC:\Program Files\PowerShell\7\pwsh.exedoes not exist andwhere pwshreturns theWindowsAppspath. - Install any tool into the user profile — e.g.
winget install GitHub.cli, or python.org's per-user Python. codex exec -s read-only 'run: git rev-parse --short HEAD'→ every command fails withCreateProcessAsUserW failed: 5,cmd=pointing at the WindowsApps alias.- Re-run with
WindowsAppsremoved from the PATH thecodexprocess sees → commands now spawn viapowershell.exe, andgitworks. codex exec -s workspace-write 'run: gh --version'→not recognized, despiteWinGet\Linksbeing present in the sandbox's$env:PATH.- Run the
Test-Path/Get-ChildItem/ full-path-execute probe above →True,UnauthorizedAccessException,ApplicationFailedException.
What is the expected behavior?
- The sandbox should be able to execute the user's toolchain. Per-user installs are the norm on Windows — winget package links, python.org per-user installs, npm globals, pipx, rustup, Store apps. If the token cannot execute anything under
C:\Users\<user>\, sandboxed mode cannot run most real projects, and-s danger-full-accessbecomes the only usable setting, which defeats the point of having a sandbox. - If this denial is deliberate isolation, it needs to say so. Right now a denied execute is reported as
CommandNotFoundException— "the term 'python' is not recognized" — which sends you looking for a PATH bug. I spent a long time ruling out PATH,shell_environment_policy.inherit,set.PATH, and profile files before probing the ACL. An explicit "sandbox denied execute on<path>" would have made it a one-minute diagnosis, and the docs should state that user-profile executables are unavailable in sandboxed mode. - Shell discovery should not select an executable the sandbox's own token cannot start. Skipping WindowsApps alias stubs, or probing the machine-wide
C:\Program Files\PowerShell\7\pwsh.exe(already referenced in the binary) before the PATH lookup, would fix symptom 1 outright.
Relationship to existing issues
#26186, #37592, #30024, #35958 and #36614 all report CreateProcessAsUserW failures, the first two with error 5. I am not claiming those share this cause. #37592's follow-up describes an intermittent failure where some commands succeed, correlated with SetFileAttributesW on C:\Users\Default; this one is total, deterministic, and fully explained by the token's inability to execute under the user profile. Filing separately rather than assuming — if a maintainer confirms a shared root cause, please close this as a duplicate.
Found while trying to run a code review with codex exec on an ordinary developer machine; nothing here is specific to the project under review. Paths redacted per the template.
2 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Your probe results pin the policy shape precisely, and it's worth framing as a design gap rather than an ACL accident: the sandbox setup (the
SetupPayloadread/write/deny roots applied as ACLs bycodex-windows-sandbox-setup— see the payload structure discussed in #38985) leaves user-profile directories stat-able but deniesFILE_LIST_DIRECTORYandFILE_EXECUTEoutside the workspace. On Windows that's fatal to tooling generally, because per-user installs are the norm: WindowsApps execution aliases (winget's only PowerShell variant, as you note),AppData\Local\Programs,WinGet\Links, npm global bins. Attributes-only visibility breaks both spawn (symptom 1) and PATH discovery (symptom 2) in one stroke — enumeration denial means PowerShell can't even see what's on PATH.Fix shapes:
PATH, plus theWindowsAppsalias directory and itsProgram Files\WindowsAppsMSIX targets (the reparse target needs execute too, or aliases keep failing with error 5).executable_rootspolicy knob so users can whitelist tool directories without opening profile data reads.codex doctorcould probe exactly your three checks (stat / enumerate / execute a PATH entry under the profile) and report the asymmetry — this class of "everything says not recognized" report becomes self-diagnosing.Option 1's PATH-derived variant fixes the default experience for the common winget/npm/python.org setups without widening reads on user documents.