apply_patch intermittently hangs/stalls without returning success or error
What version of Codex CLI is running?
codex-cli 0.133.0
What subscription do you have?
Business
Which model were you using?
gpt-5-codex
What platform is your computer?
Darwin 25.3.0 arm64 arm
What terminal emulator and version are you using (if applicable)?
Codex desktop / Codex shell environment. No terminal multiplexer.
Codex doctor report
What issue are you seeing?
apply_patch intermittently hangs or stalls while applying normal file edits.
When this happens, the tool call does not quickly return either success or a useful failure
message. The agent appears blocked waiting for apply_patch, sometimes for more than 30 seconds,
and the only practical workaround was to avoid apply_patch and use direct shell-based edits
instead. In the latest releases that workaround does not work anymore.
What steps can reproduce the bug?
The issue is intermittent, but the pattern is:
- Start a Codex session in a local code workspace.
- Ask Codex to make a small source edit.
- Codex invokes
apply_patch. - Sometimes
apply_patchstalls instead of returning success or a clear failure. - The session remains blocked until the workflow is abandoned or the agent switches to shell-
based file edits.
Example class of operation:
- edit an existing source/header/test file
- apply a small patch
- expect the patch tool to return promptly
I do not have a deterministic minimal reproducer yet.
What is the expected behavior?
apply_patch should return deterministically.
If the patch applies, it should return success promptly. If the patch cannot be applied, it should fail promptly with a clear diagnostic. It should not hang or leave the agent blocked without
feedback.
Additional information
_No response_
Showing cached comments. Read the full discussion on GitHub ↗
4 Comments
Still reproducible on
codex-cli 0.144.5on macOS arm64 (npm/Homebrew global install).Additional observations from repeated failures today:
apply_patchtool intermittently remains pending with no success/error event even for a one-file add or update. We terminated calls after 15 seconds; the target file was unchanged.~/.codex/tmp/arg0/<session>/apply_patch -> .../@openai/codex-darwin-arm64/.../bin/codex.apply_patchshim in a PTY and sending the patch on stdin usually completes immediately for small patches. This suggests a tool-bridge/stdin/completion-event boundary rather than filesystem or patch-parser failure.codex features liston 0.144.5 reportsapply_patch_freeform: removedandapply_patch_streaming_events: under development, false.codex doctor --jsonalso produced no output for 30 seconds in this environment and was terminated, so no doctor payload is attached.Expected: every dispatched patch reaches a bounded terminal outcome (
applied, explicit rejection, timeout, or cancellation), and cancellation must leave a verifiable mutation state.Current safe workaround in our automation is a 15-second fuse, verify whether the file changed, then use the same shim via PTY for small patches or a purpose-built formatter for mechanical output. This keeps work moving but is not an acceptable general editing path.
Follow-up after a true clean restart on macOS arm64 with
codex-cli 0.144.5:codex --codex-run-as-fs-helper/ headless helper processes.lsofconfirmed both Codex andcodex-code-mode-hostwere loaded from the canonical/opt/homebrew/lib/node_modules/@openai/codex/tree, not the pre-reinstall.codex-*temporary tree.apply_patchprobe under/private/tmpcompleted successfully in 0.1 s.apply_patchcall, adding one 779-byte Markdown file inside the writable workspace, hung for about 282 s until the turn was interrupted. The target file was not created and no partial write remained.apply_patchwrapper through an interactive PTY completed the same one-file patch in seconds.So the clean restart removed the stale-process confounder, but did not resolve the intermittent built-in tool hang. A successful minimal probe is not sufficient to establish recovery. The failure still appears specific to the built-in tool/app-server execution path rather than patch parsing or filesystem permissions.
Operational workaround remains: one file per patch, stop waiting at 15 s, verify whether anything landed, then use the PTY wrapper.
Root-cause update from a live sample taken while the built-in file change was stuck in
in_progress:codex --codex-run-as-fs-helperremained present with stdin/stdout/stderr pipes open.sampleof the helper produced 1,600/1,600 identical main-thread samples at:fs_helper_main -> PathUri::to_abs_path -> AbsolutePathBuf::maybe_expand_home_directory -> dirs::home_dir -> getpwuid_r -> Directory Services XPC bootstrap_look_up3 -> mach_msg2_trap.dscacheutil -q user -a uid 501completed in 0.00 s five times, so Directory Services was not globally stalled.The current source calls
home_dir()before it checksstrip_prefix('~')inmaybe_expand_home_directory(), so even an already-absolute path such as/private/tmp/...performs this unnecessary lookup:https://github.com/openai/codex/blob/315195492c80fdade38e917c18f9584efd599304/codex-rs/utils/absolute-path/src/lib.rs#L22-L39
Suggested upstream fixes:
~before callinghome_dir(); return non-tilde paths unchanged.in_progress.Additional A/B results: single patches sometimes succeed with either
code_mode_host=trueorfalse; five-call sequence prompts reproduced the first-call hang with default settings, withcode_mode_host=false, and withapply_patch_streaming_events=true. This does not appear to be caused solely by those feature flags or by auto-review.I prepared and locally validated a focused fix for the root cause described above: https://github.com/ysl-repo/codex/commit/fc84d63
The change makes
AbsolutePathBuf::maybe_expand_home_directorycheck for a leading~before invokingdirs::home_dir(). It also adds a resolver-injection regression test that asserts a non-tilde absolute path is returned unchanged without calling the home resolver.Local validation on current
main:just fmt: PASSjust test -p codex-utils-absolute-path: PASS (26/26, 1 existing skipped test)just fix -p codex-utils-absolute-path: PASSgit diff --check: PASSThe branch is
ysl-repo:fix/avoid-home-dir-for-non-tilde-paths. I have not opened a PR becausedocs/contributing.mdsays external PRs require an explicit maintainer invitation. If this approach matches the intended fix, would a maintainer please confirm/invite the PR? I can open it immediately and sign the CLA.