macOS 0.122.0: apply_patch hangs under workspace-write but succeeds under danger-full-access
Summary
On macOS ARM64 with codex-cli 0.122.0, the internal apply_patch tool can hang indefinitely under the normal sandboxed path (workspace-write / --full-auto) on a tiny local file.
The same exact patch succeeds immediately when the nested Codex run uses --dangerously-bypass-approvals-and-sandbox (danger-full-access).
This looks distinct from #17834:
#17834is the earlier macOS0.120.0case whereapply_patchreturned a ~10s timeout with exit code124- this report is the newer
0.122.0case whereapply_patchis dispatched but then produces no success or error until interrupted/killed
Environment
- OS: macOS 26.3.1 (build
25D771280a) - Arch:
arm64 - Codex CLI:
codex-cli 0.122.0
Minimal repro
mkdir -p /tmp/codex-test
printf 'one\ntwo\n' > /tmp/codex-test/test.txt
Interactive repro:
cd /tmp/codex-test
codex
Then ask Codex:
use apply_patch to change "two" to "three" in test.txt
Non-interactive repro for the same sandboxed path:
codex exec --json --full-auto --skip-git-repo-check --cd /tmp/codex-test \
'use apply_patch to change "two" to "three" in test.txt'
Observed behavior under workspace-write
Codex reads test.txt, emits the apply_patch tool call for the expected one-line diff, and then nothing comes back from the tool path.
The patch used was:
*** Begin Patch
*** Update File: test.txt
@@
-two
+three
*** End Patch
Observed outcome:
- no success output
- no parse error
- no deterministic tool error
- file remains unchanged
- the session only ends after manual interrupt or an external timeout wrapper kills the run
In a fresh batch I ran the same --full-auto repro 5 times with an outer 45-second wrapper. Results:
0/5succeeded5/5hung until killed by the wrapper5/5lefttest.txtunchanged as:
one
two
Comparison against danger-full-access
Running the same repro with:
codex exec --json --dangerously-bypass-approvals-and-sandbox --skip-git-repo-check --cd /tmp/codex-test \
'use apply_patch to change "two" to "three" in test.txt'
succeeded immediately with normal tool output:
Success. Updated the following files:
M /tmp/codex-test/test.txt
and the file became:
one
three
Why this seems important
This strongly suggests the problem is in the sandboxed filesystem / helper path used by apply_patch, not in the patch text itself. That is an inference from the behavior above, not a confirmed root cause.
Expected behavior
The same minimal patch should either:
- succeed normally under
workspace-write, or - fail quickly with a deterministic tool error
It should not hang indefinitely on a 2-line local file.
Related
- Related but distinct: #17834
If useful, I can provide redacted session JSONL excerpts showing the workspace-write hang and the danger-full-access success.
8 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Follow-up data point from the same minimal
/tmp/codex-testrepro on the same machine.I reran the nested
danger-full-access/--dangerously-bypass-approvals-and-sandboxpath 5 more times with the same patch and a 45-second outer wrapper.Results:
5/5succeeded0/5hung5/5changedtest.txtfrom:to:
Durations were roughly 17-21 seconds per run.
So the current local split is:
workspace-write:0/5success,5/5hangdanger-full-access:5/5success,0/5hangThat still points at the sandboxed path as the differentiator rather than the patch text itself.
Do you have reason to believe that this behavior changed recently? I'm trying to determine if it's a regression.
Good question. On April 14th, I'd primarily get timeouts (Issue #17834) now I get complete hangs, so I'd say it's gotten worse and its become more predictable.
We haven't had other reports of #17834 or this issue, so I'm wondering if this is something that's specific to your machine. It's unlikely we'll be able to prioritize an investigation unless this is reported by other users. Since codex is open source, you could clone the repo and work with Codex to try to identify a root cause.
I found two concrete issues in the macOS sandboxed fs-helper path:
codex-rs/utils/absolute-path/src/lib.rs,AbsolutePathBufwas callinghome_dir()even for ordinary absolute paths like/tmp/.... That should only happen for~paths.codex-rs/exec-server/src/fs_sandbox.rs, the fs-helper is launched withenv_clear()and a very small allowlist, which drops__CF_USER_TEXT_ENCODINGon macOS.__CF_USER_TEXT_ENCODING
is a private macOS/CoreFoundation env var associated with per-user text encoding state (~/.CFUserTextEncoding`).In the sampled blocked stacks, both of those led into the same Apple fallback path (
getpwuid_r -> notify_register_check -> bootstrap_look_up2) inside the sandboxed fs-helper. That helper path is not used under YOLO, which explains why it works. On my machine, that fallback path can block. On other machines it may return quickly, which would explain why this can be a real code-level bug but still only show up for one reporter so far.I patched both locally:
__CF_USER_TEXT_ENCODINGfor the macOS fs-helperhome_dir()lookup unless the path actually starts with~I also added regression coverage for the non-
~path case.I couldn’t open a PR because this repo currently restricts PR creation, but I pushed a branch to my fork in case its useful.
@etraut-openai Any chance we can get this fix into an upcoming version? Both changes are contained and quality improvements on their own even without this bug
Independent data point from a second reporter, plus a re-test on a current release.
We run Codex non-interactively in automated build workers on macOS, where
apply_patchwriting multi-line files is the hot path. Back in July we hit exactly the symptom described here and shipped a workaround that force-upgrades--sandbox workspace-writetodanger-full-accessfor our build workers.Our July reproduction (codex-cli 0.142.5, macOS, Intel x86_64): a ~150-line single-file
apply_patchhung3/3under--sandbox workspace-writeand succeeded3/3in ~34s underdanger-full-access. Same split reported here.Re-test today on codex-cli 0.146.0, same machine (macOS 24.6.0, Intel Core i9, x86_64):
| sandbox mode | result | wall clock | sandboxed fs-helper observed |
|---|---|---|---|
|
workspace-write| 3/3 success | 60.6s / 65.0s / 67.8s | yes (1 helper per run) ||
danger-full-access| 3/3 success | 59.3s / 58.7s / 66.5s | no |Method: a throwaway git repo under
/tmpper run,codex exec --sandbox <mode> --json --skip-git-repo-check, prompt instructing a singleapply_patchcall that creates a 150-line file, 120s hard timeout with process-group kill (the original failure hung indefinitely, so a timeout is the hang detector). Each run was verified to have actually taken the patch path: the JSONL showsfile_changegoingitem.started->item.completed, no shell/command fallback, and the resulting file has exactly 150 lines. The helper column matters as a control:psshows a--codex-run-as-fs-helperchild during everyworkspace-writerun and none underdanger-full-access, so the sandboxed helper path really was exercised rather than silently skipped.So: no longer reproducible for us on 0.146.0. The
workspace-writetimings are now indistinguishable fromdanger-full-access.One correction to our own earlier evidence that may be worth recording here, since it cuts against a simple "fixed in a later release" reading. #25118 ("exec-server: preserve fs helper CoreFoundation env", the
__CF_USER_TEXT_ENCODINGfix) merged 2026-05-29 and is an ancestor ofrust-v0.142.5— the exact version we were on when we saw the hang in July. So our July failure happened with that fix already present. Either our July hang had a second contributing cause (we were separately dealing with leaked--codex-run-as-fs-helperorphans from SIGKILLed runs, which is a plausible confound on our side), or the remaining trigger is intermittent and environment-sensitive in the way @andrewalex and #24956 both describe. We can't cleanly separate those from here, so we're reporting it as "not reproducible on 0.146.0" rather than "confirmed fixed by a specific commit".Two things that might still be worth maintainer attention:
AbsolutePathBufcallinghome_dir()even for ordinary absolute paths that don't start with~— appears to have landed since (currentcodex-rs/utils/absolute-path/src/lib.rsguards the lookup behind a~prefix check). Worth confirming that's intentional coverage of their report rather than an incidental change, since they noted they couldn't open a PR because the repo restricts PR creation and pushed a branch to their fork instead. If their regression tests aren't upstream, they'd be cheap insurance against this class recurring.Fixes #19020and carried a much deeper reduction of the:minimalpolicy-composition bug, was closed by the stale-PR bot after 14 days with no maintainer review — not on merit. If that diagnosis is correct, the underlying policy defect (native runtime permissions being dropped whenever:root = readsubsumes:minimal) is still present regardless of whether the__CF_USER_TEXT_ENCODINGpatch masks the symptom. That seems worth a look before this issue is closed.Given the above, this issue is probably closeable on the original symptom, but we'd suggest confirming #24956's policy finding separately rather than letting it lapse with the bot closure. Happy to re-run our harness against any candidate build or a specific config if that's useful.