apply_patch tool hangs indefinitely on tiny patch in /private/tmp
What happened?
The Codex apply_patch tool hangs indefinitely even for a one-line patch against a tiny file in /private/tmp. This reproduces after restarting and updating Codex, and it affects multiple sessions on the same macOS machine.
Normal shell file writes and reads complete immediately, so this appears isolated to the apply_patch tool/tool-bridge path rather than disk, git, or the target repository.
Environment
- Codex CLI:
codex-cli 0.133.0 - Platform from
codex doctor --json:macos-aarch64 - Install method: npm package
@openai/codex - Auth mode: ChatGPT auth
- Sandbox: restricted filesystem + restricted network, approval
OnRequest codex doctorstate DB checks:state_5.sqlite,logs_2.sqlite, andgoals_1.sqliteall reported integrityok- Disk check: about 80 GiB free; inode pressure negligible
codex doctor also reported provider reachability/DNS failures for chatgpt.com/api.github.com, but the session itself could continue and normal shell commands worked. The apply_patch hang reproduced locally in /private/tmp, before any network operation should be needed.
Minimal reproduction
- Create a tiny file:
mkdir -p /private/tmp/apply-patch-test && printf 'a\n' > /private/tmp/apply-patch-test/t.txt && cat /private/tmp/apply-patch-test/t.txt
This completes immediately and prints a.
- Ask Codex to run this
apply_patchtool call:
*** Begin Patch
*** Update File: /private/tmp/apply-patch-test/t.txt
@@
-a
+b
*** End Patch
Expected behavior
The tool should return quickly and update the file from a to b.
Actual behavior
The tool call does not return. After about 100 seconds I interrupted it. The file remained unchanged as a.
Earlier, a larger apply_patch call in a separate worktree also hung until manually interrupted. Local log timing for that case showed the task closing only after interrupt, with approximately time.idle=8104s.
Relevant local log pattern
From ~/.codex/log/codex-tui.log, the pattern is:
ToolCall: apply_patch ...- no success/error/completion line for the tool call
- manual interrupt later
- task closes only after interrupt, with long idle time
For the tiny /private/tmp repro, the preceding normal shell command was logged and completed immediately, then the apply_patch tool call was logged and never completed until interrupt.
Notes
This is blocking because Codex coding sessions rely on apply_patch for safe manual edits. The current workaround is to avoid apply_patch and use shell-based file edits followed by git diff verification, but that is less safe and bypasses the intended workflow.
3 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Thanks for the minimal repro. This looks consistent with the same failure class as #24407/#24155/#24206, but with an important detail: the repro uses a sandboxed
/private/tmppath and normal shell writes still work.One implementation detail that may help narrow this down: in the current Rust code, the
apply_patchruntime awaitscodex_apply_patch::apply_patch(...)directly and reportstimed_out: false; I do not see an exec-style timeout around that runtime path. In the sandboxed filesystem implementation, file operations go through the sandboxed filesystem helper, whose runner spawns the helper process, sends the request over stdin, and then awaitswait_with_output()without a visible timeout. That differs from the shell exec path, which has explicit expiration and output-drain timeout handling.So a useful next probe may be to instrument the sandboxed filesystem helper request/response boundary for this repro: confirm whether the helper process is spawned, whether stdin is fully written/shutdown, whether the helper exits, and whether the parent is stuck waiting for helper output. If that is the stuck boundary, adding a bounded timeout/error path around the helper wait would at least turn this class of hangs into actionable failures.
I have not reproduced this on macOS locally, so I would treat this as code-path narrowing rather than a confirmed root cause.
this is very annoying now, every change I made I have to instruct codex not to use apply patch , and the underlying model does not follow always, is there any workaround on this?