apply_patch intermittently hangs/stalls without returning success or error

Open 💬 5 comments Opened May 22, 2026 by odraccir1

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:

  1. Start a Codex session in a local code workspace.
  2. Ask Codex to make a small source edit.
  3. Codex invokes apply_patch.
  4. Sometimes apply_patch stalls instead of returning success or a clear failure.
  5. 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_

View original on GitHub ↗

4 Comments

ysl-repo · 1 month ago

Still reproducible on codex-cli 0.144.5 on macOS arm64 (npm/Homebrew global install).

Additional observations from repeated failures today:

  • The internal apply_patch tool 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.
  • The per-session shim is a symlink such as ~/.codex/tmp/arg0/<session>/apply_patch -> .../@openai/codex-darwin-arm64/.../bin/codex.
  • Starting that same apply_patch shim 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.
  • Long single-line input through the PTY fallback can itself hit terminal input-buffer/control-character corruption, so PTY is only a partial workaround.
  • codex features list on 0.144.5 reports apply_patch_freeform: removed and apply_patch_streaming_events: under development, false.
  • codex doctor --json also 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.

ysl-repo · 1 month ago

Follow-up after a true clean restart on macOS arm64 with codex-cli 0.144.5:

  • Reinstalled the official global package and fully exited the old foreground session.
  • Removed confirmed orphaned codex --codex-run-as-fs-helper / headless helper processes.
  • In the new session, lsof confirmed both Codex and codex-code-mode-host were loaded from the canonical /opt/homebrew/lib/node_modules/@openai/codex/ tree, not the pre-reinstall .codex-* temporary tree.
  • A one-line built-in apply_patch probe under /private/tmp completed successfully in 0.1 s.
  • The next real built-in apply_patch call, 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.
  • Immediately afterward, invoking the same apply_patch wrapper 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.

ysl-repo · 1 month ago

Root-cause update from a live sample taken while the built-in file change was stuck in in_progress:

  • The parent Codex process was waiting and a live child codex --codex-run-as-fs-helper remained present with stdin/stdout/stderr pipes open.
  • A 2-second macOS sample of 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.

  • The helper had not reached the requested write; after cancellation the probe directory still contained zero files.
  • Normal unsandboxed dscacheutil -q user -a uid 501 completed in 0.00 s five times, so Directory Services was not globally stalled.

The current source calls home_dir() before it checks strip_prefix('~') in maybe_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:

  1. Check for a leading ~ before calling home_dir(); return non-tilde paths unchanged.
  2. Add a bounded timeout and explicit terminal error around fs-helper RPC, so a blocked OS lookup cannot leave file change permanently in_progress.

Additional A/B results: single patches sometimes succeed with either code_mode_host=true or false; five-call sequence prompts reproduced the first-call hang with default settings, with code_mode_host=false, and with apply_patch_streaming_events=true. This does not appear to be caused solely by those feature flags or by auto-review.

ysl-repo · 1 month ago

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_directory check for a leading ~ before invoking dirs::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: PASS
  • just test -p codex-utils-absolute-path: PASS (26/26, 1 existing skipped test)
  • just fix -p codex-utils-absolute-path: PASS
  • git diff --check: PASS

The branch is ysl-repo:fix/avoid-home-dir-for-non-tilde-paths. I have not opened a PR because docs/contributing.md says 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.

Showing cached comments. Read the full discussion on GitHub ↗