Summary
A single zero-byte-filled state file permanently breaks Codex sandbox setup, and the failure survives a full uninstall/reinstall because the file lives in CODEX_HOME rather than in the app package. The app then shows the "Finish Windows setup" screen with "Windows setup didn't finish" on every launch, and "Try Windows setup again" fails instantly without ever raising a real UAC prompt.
The underlying trigger is an unclean shutdown (power loss / hard reset) while Codex is running. NTFS records the file's allocated size but never flushes its contents, so on reboot the file exists at its original length and is filled entirely with NUL (0x00) bytes. The JSON/TOML parsers then fail at the first byte.
This appears to be the actual root cause behind several existing reports that were attributed to Windows Home / Windows Sandbox availability, e.g. #28566 and #32492.
Root cause
codex-windows-sandbox-setup.exe reads <CODEX_HOME>/.sandbox/deny_read_acl_state.json unconditionally at startup. When that file is NUL-filled, setup aborts:
setup error: apply deny-read ACLs
Caused by:
0: parse deny-read ACL state <CODEX_HOME>\.sandbox\deny_read_acl_state.json
1: expected value at line 1 column 1
setup refresh: exited with status ExitStatus(ExitStatus(1))
expected value at line 1 column 1 is the parser hitting 0x00 as the first byte.
Setup then writes .sandbox/setup_error.json, which persists the failed state so the "setup didn't finish" screen reappears on every subsequent launch — even after the corrupt file itself would otherwise be harmless.
<CODEX_HOME>/config.toml was corrupted the same way in the same event (correct file size, 100% NUL bytes), which independently prevents config load.
Why reinstalling does not help
Remove-AppxPackage removes the package but leaves both CODEX_HOME and the app's per-user LocalCache/LocalState intact. The corrupt state is re-read immediately by the fresh install, so the user sees an identical failure and reasonably concludes the app itself is broken.
Environment
- Windows 11 Home Single Language, build 10.0.26200 (x64)
- ChatGPT/Codex desktop app
26.721.4979.0 (also reproduced on 26.715.4045.0)
- Sandbox marker
version: 5; CodexSandboxOffline / CodexSandboxOnline users present and enabled
- WebView2 Runtime 150.0.4078.99, intact
- UAC enabled (
EnableLUA = 1), user is a local administrator
Worth noting: Windows Sandbox is not the issue here. That optional feature is unavailable on Home SKUs by design, and Codex's own ACL/restricted-token sandbox does not require it. Setup fails purely on the unparseable state file.
Steps to reproduce
- Run the Codex desktop app normally so
.sandbox/deny_read_acl_state.json exists.
- Hard-power-off the machine while the app is running (or simulate: overwrite the file with
NUL bytes of the same length).
- Boot and launch the app.
Expected: setup detects the unreadable state file, discards it, and regenerates a default.
Actual: setup aborts; "Windows setup didn't finish" appears on every launch; "Try Windows setup again" fails instantly; reinstalling does not clear it.
Minimal simulation of the corrupt state:
$p = "$env:USERPROFILE\.codex\.sandbox\deny_read_acl_state.json"
[System.IO.File]::WriteAllBytes($p, (New-Object byte[] (Get-Item $p).Length))
Workaround
Fully exit the app (including tray), then delete the corrupt state and let it regenerate:
Remove-Item "$env:USERPROFILE\.codex\.sandbox\deny_read_acl_state.json" -Force
Remove-Item "$env:USERPROFILE\.codex\.sandbox\setup_error.json" -Force
# only if it is also NUL-filled:
Remove-Item "$env:USERPROFILE\.codex\config.toml" -Force
Both files regenerate correctly on next launch (deny_read_acl_state.json → {"principals": {}}), setup completes, and the log shows setup binary completed / read ACL run completed / errors=[]. No reinstall required.
To detect the condition:
$p = "$env:USERPROFILE\.codex\.sandbox\deny_read_acl_state.json"
$b = [System.IO.File]::ReadAllBytes($p)
"NUL bytes: $(($b | Where-Object { $_ -eq 0 }).Count) / $($b.Length)"
Suggested fix
- Treat an unparseable
deny_read_acl_state.json as empty state rather than a fatal error — log a warning, back the file up, and regenerate the default. Nothing in it is unrecoverable; it rebuilds from {"principals": {}}.
- Apply the same tolerance to other
CODEX_HOME state files corrupted by the same mechanism (config.toml was hit in the same event).
- Write these files atomically (write to a temp file,
FlushFileBuffers, then rename) so an unclean shutdown leaves either the old or the new content, never a NUL-filled file.
- Surface the underlying parse error in the setup UI. The current screen implies a declined UAC prompt, which sends users toward UAC settings, BIOS virtualization, and reinstalls — none of which can fix a corrupt state file.
Related
Summary
A single zero-byte-filled state file permanently breaks Codex sandbox setup, and the failure survives a full uninstall/reinstall because the file lives in
CODEX_HOMErather than in the app package. The app then shows the "Finish Windows setup" screen with "Windows setup didn't finish" on every launch, and "Try Windows setup again" fails instantly without ever raising a real UAC prompt.The underlying trigger is an unclean shutdown (power loss / hard reset) while Codex is running. NTFS records the file's allocated size but never flushes its contents, so on reboot the file exists at its original length and is filled entirely with
NUL(0x00) bytes. The JSON/TOML parsers then fail at the first byte.This appears to be the actual root cause behind several existing reports that were attributed to Windows Home / Windows Sandbox availability, e.g. #28566 and #32492.
Root cause
codex-windows-sandbox-setup.exereads<CODEX_HOME>/.sandbox/deny_read_acl_state.jsonunconditionally at startup. When that file is NUL-filled, setup aborts:expected value at line 1 column 1is the parser hitting0x00as the first byte.Setup then writes
.sandbox/setup_error.json, which persists the failed state so the "setup didn't finish" screen reappears on every subsequent launch — even after the corrupt file itself would otherwise be harmless.<CODEX_HOME>/config.tomlwas corrupted the same way in the same event (correct file size, 100%NULbytes), which independently prevents config load.Why reinstalling does not help
Remove-AppxPackageremoves the package but leaves bothCODEX_HOMEand the app's per-userLocalCache/LocalStateintact. The corrupt state is re-read immediately by the fresh install, so the user sees an identical failure and reasonably concludes the app itself is broken.Environment
26.721.4979.0(also reproduced on26.715.4045.0)version: 5;CodexSandboxOffline/CodexSandboxOnlineusers present and enabledEnableLUA = 1), user is a local administratorWorth noting: Windows Sandbox is not the issue here. That optional feature is unavailable on Home SKUs by design, and Codex's own ACL/restricted-token sandbox does not require it. Setup fails purely on the unparseable state file.
Steps to reproduce
.sandbox/deny_read_acl_state.jsonexists.NULbytes of the same length).Expected: setup detects the unreadable state file, discards it, and regenerates a default.
Actual: setup aborts; "Windows setup didn't finish" appears on every launch; "Try Windows setup again" fails instantly; reinstalling does not clear it.
Minimal simulation of the corrupt state:
Workaround
Fully exit the app (including tray), then delete the corrupt state and let it regenerate:
Both files regenerate correctly on next launch (
deny_read_acl_state.json→{"principals": {}}), setup completes, and the log showssetup binary completed/read ACL run completed/errors=[]. No reinstall required.To detect the condition:
Suggested fix
deny_read_acl_state.jsonas empty state rather than a fatal error — log a warning, back the file up, and regenerate the default. Nothing in it is unrecoverable; it rebuilds from{"principals": {}}.CODEX_HOMEstate files corrupted by the same mechanism (config.tomlwas hit in the same event).FlushFileBuffers, then rename) so an unclean shutdown leaves either the old or the new content, never a NUL-filled file.Related