[Windows 11] apply_patch stalls for 40–60 seconds before one-line file mutation in Codex CLI 0.144.1
What version of Codex CLI is running?
codex-cli 0.144.1
What subscription do you have?
ChatGPT Plus
Which model were you using?
gpt-5.6-sol, reasoning high The same severe apply_patch slowdown also reproduced with multiple other GPT-5.6 Codex models, so it does not appear to be specific to gpt-5.6-sol.
What platform is your computer?
Windows 11 x64, native Windows environment, not WSL
What terminal emulator and version are you using (if applicable)?
Native PowerShell session on Windows 11
Codex doctor report
Not collected. Codex CLI /status output is included in Additional information.
What issue are you seeing?
apply_patch consistently takes approximately 40–60 seconds to perform a trivial one-line file edit on native Windows 11.
Direct filesystem writes through Node.js, Bun, and PowerShell complete in under approximately one second of total tool-call wall time, while the actual filesystem mutation itself takes milliseconds or less.
An independent Bun watcher polling the target file every millisecond showed that virtually the entire apply_patch delay occurs before the target file is mutated. Once the mutation becomes visible, the tool call completes within 1–17 ms.
There is no visible approval prompt during the delay. Codex stalls silently, the file eventually changes, and the tool call then returns almost immediately.
Full wall-clock benchmark
All measurements cover the complete Codex tool call, from immediately before dispatch until the result returned.
| Location | Method | Run 1 | Run 2 | Run 3 | Median |
|---|---:|---:|---:|---:|---:|
| Repository | apply_patch | 53.438 s | 49.878 s | 50.377 s | 50.377 s |
| Repository | Bun | 2.220 s | 1.498 s | 0.836 s | 1.498 s |
| Repository | Node.js node:fs | 0.682 s | 0.625 s | 0.687 s | 0.682 s |
| Repository | PowerShell | 1.245 s | 0.780 s | 0.792 s | 0.792 s |
| C:\tmp | apply_patch | 49.462 s | 52.871 s | 52.469 s | 52.469 s |
| C:\tmp | Bun | 0.579 s | 0.691 s | 0.495 s | 0.579 s |
| C:\tmp | Node.js node:fs | 0.458 s | 0.428 s | 0.452 s | 0.452 s |
| C:\tmp | PowerShell | 0.398 s | 0.888 s | 0.705 s | 0.705 s |
Additional apply_patch calls made while preparing the benchmark took:
- 38.933 seconds
- 46.482 seconds
- 60.449 seconds
Actual filesystem write durations
| Location | Method | Run 1 | Run 2 | Run 3 | Median |
|---|---:|---:|---:|---:|---:|
| Repository | Bun | 0.699 ms | 0.584 ms | 0.611 ms | 0.611 ms |
| Repository | Node.js | 0.405 ms | 0.296 ms | 0.315 ms | 0.315 ms |
| Repository | PowerShell | 33.536 ms | 31.954 ms | 31.627 ms | 31.954 ms |
| C:\tmp | Bun | 0.599 ms | 0.499 ms | 0.482 ms | 0.499 ms |
| C:\tmp | Node.js | 0.281 ms | 0.367 ms | 0.342 ms | 0.342 ms |
| C:\tmp | PowerShell | 31.323 ms | 31.489 ms | 30.742 ms | 31.323 ms |
Patch phase timing
An independent Bun process polled the target file every millisecond.
| Location | Run | Before mutation | After mutation | Total |
|---|---:|---:|---:|---:|
| Repository | 1 | 53.421 s | 17 ms | 53.438 s |
| Repository | 2 | 49.869 s | 9 ms | 49.878 s |
| Repository | 3 | 50.371 s | 6 ms | 50.377 s |
| C:\tmp | 1 | 49.460 s | 2 ms | 49.462 s |
| C:\tmp | 2 | 52.870 s | 1 ms | 52.871 s |
| C:\tmp | 3 | 52.461 s | 8 ms | 52.469 s |
The benchmark cannot distinguish whether the delay happens before the patch helper process starts or during pre-write validation inside the helper. It does definitively localize the delay to the combined pre-write phase.
Troubleshooting already performed
The behavior did not materially improve after:
- closing Android Studio and the Android emulator,
- temporarily disabling Windows real-time antivirus protection,
- testing outside the repository under
C:\tmp, - temporarily excluding Git metadata as the cause,
- testing multiple GPT-5.6 Codex models,
- restarting and using fresh Codex sessions.
The repository contains approximately 85,000 filesystem entries, including approximately 80,000 under node_modules, but direct enumeration completed in approximately 0.5 seconds.
The delay is therefore unlikely to be caused by disk performance, normal filesystem writes, Git, node_modules, repository size, Android Studio, the Android emulator, or Windows real-time antivirus scanning.
The current workaround is to avoid apply_patch and use targeted Node.js node:fs edits instead.
What steps can reproduce the bug?
- Start Codex CLI
0.144.1on native Windows 11.
- Use a normal workspace session with permissions set to
Workspace (Ask for approval).
- Create a disposable text file containing a single line:
a.
- Ask Codex to use
apply_patchto change that line fromatob.
- Measure the full tool-call wall time, from dispatch until the tool returns.
- Observe that no approval prompt appears. The
apply_patchcall stalls silently for approximately 40–60 seconds.
- Monitor the target file from a separate process. The file remains unchanged during virtually the entire delay.
- Once the mutation becomes visible, the tool call completes within several milliseconds.
- Repeat the test in both:
- the active repository;
- a disposable directory under
C:\tmp.
- Compare the result with an equivalent targeted edit using Node.js
node:fs, Bun, or PowerShell. These methods complete in under approximately one second of total tool-call wall time.
The behavior reproduces consistently across repeated runs.
What is the expected behavior?
A trivial one-line apply_patch operation should start promptly and complete within a few seconds.
Its latency should be reasonably comparable to other local file-editing methods and should not introduce a consistent 40–60 second pre-write delay before every file mutation.
Additional information
Sanitized /status
OpenAI Codex v0.144.1
Model: gpt-5.6-sol
Reasoning: high
Directory: Windows workspace
Permissions: Workspace (Ask for approval)
Collaboration mode: Default
Subscription: ChatGPT Plus
````
No permission or approval dialog appears during the delay.
The issue also reproduced with multiple other GPT-5.6 Codex models, so it does not appear to be specific to `gpt-5.6-sol`.
A private OpenAI Support ticket containing the complete benchmark and session identifier has already been escalated to a support specialist. I am not including the account email address or full private session identifier in this public issue.
Potentially related issue: #32314.
The behavior described here is narrower and specifically isolates approximately 50 seconds of latency in the pre-write path of `apply_patch`.
8 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
I reproduced and narrowed this down further on native Windows with
codex-cli 0.144.0.After fixing an unrelated ACL propagation problem in one writable root, trivial
apply_patchcalls became reliable but still showed operation-dependent latency:| Operation | Full tool time |
--codex-run-as-fs-helperstarts ||---|---:|---:|
| Add file | 2.7 s | 3 |
| Update file | 3.6 s | 4 |
| Delete file | 4.5 s | 5 |
Each fs-helper cycle took approximately 0.84–0.90 seconds. The actual
codex-windows-sandbox-setup.exerefresh took only about 95 ms and consistently reported:The remaining time was spent repeatedly starting the fs-helper, preparing the sandbox wrapper, resolving/copying the command runner, and performing one filesystem RPC.
The number of helper starts matches the current implementation:
Relevant code:
codex-rs/apply-patch/src/invocation.rscodex-rs/apply-patch/src/lib.rscodex-rs/exec-server/src/fs_helper.rsThis suggests that one logical
apply_patchoperation currently prepares a fresh Windows sandbox for every individual filesystem RPC instead of preparing it once and executing the complete patch inside one helper/session.I also found a separate multiplier that can explain the reported 40–60 second cases. One writable root inherited a stale
CodexSandboxUsersACE containingFILE_DELETE_CHILD(0x1301ff) from its parent. Codex requires0x1301bfand treatsFILE_DELETE_CHILDas requiring refresh. Because the unwanted ACE was inherited, each refresh added the correct explicit ACE but could not eliminate the inherited one. Every subsequent helper call therefore triggeredSetNamedSecurityInfoWagain, causing Windows to propagate ACL changes through approximately 235,000 cached files.After removing the stale inheritable parent ACE:
granting write ACEentries appeared.apply_patchdropped to 2.7–4.5 seconds.There appear to be two compounding problems:
FILE_DELETE_CHILDACE makeswrite_root_needs_refresh()permanently true.Potential fixes would be:
@fcoury
I confirmed the inherited-ACE multiplier described above on native Windows 10 Pro 19045 with Codex CLI 0.144.1.
My writable root was:
X:\example\project\appIt had two CodexSandboxUsers Allow ACEs:
0x1301bf(Modify, Synchronize) - correct0x1301ff(DeleteSubdirectoriesAndFiles, Modify, Synchronize) - staleThe inherited
0x1301ffACE originated from an explicit container/object-inheritable ACE on the parent:X:\example\projectBecause Allow ACE permissions are cumulative, adding the correct explicit
0x1301bfACE at the writable root could not cancel the inherited FILE_DELETE_CHILD (0x40) permission. The effective ACL therefore continued to contain0x1301ff, apparently causing write_root_needs_refresh() to remain true on every filesystem RPC.Before fixing the parent ACL, trivial sandboxed filesystem reads consistently took approximately 25-26 seconds, and
codex-windows-sandbox-setup.exewas invoked repeatedly. The workspace is on a local fixed NTFS volume, not a network share. I removed only the stale0x1301ffACE from the parent and retained the correct explicit0x1301bfACE on app. Afterward, app had only the correct non-inherited ACE. The huge delay on tool call disappeared completely.This appears to confirm two separate compounding problems:
0x1301ffACE makes ACL refresh permanently necessary because it cannot be corrected by adding a narrower ACE at the writable-root child.I also noticed that the tool call is extremely slow, which makes a simple edit task to take forever. I'm also using windows 11
@rtellez91 As I said above, check the writable roots
Root-caused this. The stall is a non-converging per-command DACL rewrite triggered by a stale inherited ACE, which matches the
0x1301BF(explicit, correct) +0x1301FF(inherited, stale) state reported above.Mechanism (codex-rs @ current main):
ensure_allow_write_aces(windows-sandbox-rs/src/acl.rs) treats a write root as needing a refresh when the cap SID has any ACE containingFILE_DELETE_CHILD(disallow_mask). The check (dacl_mask_allows) skipsINHERIT_ONLY_ACEbut countsINHERITED_ACEentries.CodexSandboxUsers/cap-SID grant with mask0x1301FF(includesFILE_DELETE_CHILD) on an ancestor directory, so the workspace root inherits it.SetEntriesInAclW(SET_ACCESS) +SetNamedSecurityInfoW, which only replaces explicit ACEs for the trustee. It can never remove the inherited ACE.SetNamedSecurityInfoWon the root re-propagates inheritable ACEs through the entire workspace tree — seconds to minutes on large projects.FILE_DELETE_CHILDbit is still there → rewrite again. Loop never converges.This runs on every command via
spawn_prep.rs(ensure_allow_write_aces), and the elevated setup helper loops the same way throughwrite_root_needs_refresh(bin/setup_main/win.rs), which explains why the wholeapply_patchwall time is spent before the file mutation, and why switching the sandbox to unelevated reduces (but doesn't remove) the stall.Fix outline: the staleness checks should count only explicit ACEs, because explicit ACEs are all a rewrite can replace:
explicit_onlyvariant ofdacl_mask_allows/path_mask_allowsthat skipsINHERITED_ACEentries;disallow_maskcheck inensure_allow_mask_aces_with_inheritance_impland for theFILE_DELETE_CHILDprobe inwrite_root_needs_refresh.A stale explicit grant on the root itself is still detected and fixed by a single converging rewrite (existing
write_root_refresh_replaces_stale_delete_child_granttest). Effective access rights don't change — the old per-command rewrites never removed the inherited grant either (that half of the problem is #32915's territory and needs the ancestor's DACL cleaned, which is outside the sandbox's write roots).I have this implemented with a regression test (
write_root_refresh_ignores_inherited_stale_delete_child_grant: seed an inheritable stale grant on a parent, create the workspace under it, assert no refresh/rewrite is triggered): https://github.com/lyy0709/codex/commit/0a77d53a92c96f1dfd176397f33d7a4ac47d8c73 —cargo check --all-targetspasses forx86_64-pc-windows-gnu. Per the contribution policy I haven't opened a PR; happy to submit it if invited.I am also impacted by this, I’m using Codex CLI 0.144.4 in the VS Code integrated PowerShell terminal on Windows 11.
The project is on a healthy NVMe drive. I repeated the direct patch test on a separate NVMe drive and got about 37 s for creation, so this does not appear disk-specific. Ordinary local file reads and Git status are sub-second.
I can reproduce this in the VS Code Codex extension on Windows 11.
Environment:
Results:
The sandbox logs repeatedly show:
codex.exe --codex-run-as-fs-helper
These filesystem-helper processes start roughly every 8–18 seconds during the delay, with no corresponding SUCCESS or FAILURE entry. The patch eventually succeeds.
This appears consistent with the pre-mutation delay reported here. The repeated fs-helper launches may help narrow down where the retry/stall occurs.