-
Notifications
You must be signed in to change notification settings - Fork 10.2k
Frequent apply_patch failures after 0.117.0 appear to come from the execution/runtime path, not from patch grammar parsing #16102
Description
What version of Codex CLI is running?
117
What subscription do you have?
200usd
Which model were you using?
gpt 5.4
What platform is your computer?
No response
What terminal emulator and version are you using (if applicable)?
No response
What issue are you seeing?
Title
Frequent apply_patch failures after 0.117.0 appear to come from the execution/runtime
path, not from patch grammar parsing
Session Reference
Codex session id: "019d310c-4996-7d52-b3e6-67a59ad0d0ad"
Summary
After upgrading to codex-cli 0.117.0, I started seeing apply_patch fail much more
frequently than before.
After reviewing the target session log and the current open-source Codex code, my
conclusion is:
- This does not look like a primary apply_patch parser/grammar regression.
- It looks much more like an execution-path regression around the runtime/delegation layer
that actually runs the verified patch. - The timing strongly overlaps with 0.117.0 changes that made the app-server TUI default
and refactored execution/environment handling through exec-server abstractions.
Why I do not think this is mainly a patch grammar problem
In the referenced session, the failures are not all the same kind.
I found at least three distinct failure classes:
- Invalid patch target type
The session attempted to patch a compiled .pyc file under pycache, which failed
with:
stream did not contain valid UTF-8
That is not a parser regression. That is a bad patch target.
- Invalid patch body
The session also produced:
apply_patch verification failed: invalid hunk at line 4, Update hunk does not contain
any lines
This matches current open-source parser behavior exactly. The parser still explicitly
rejects empty update hunks.
- Execution-layer ENOENT
The most interesting failures were repeated:
execution error: Io(Os { code: 2, kind: NotFound, message: "No such file or
directory" })
These happened after the patch had already been parsed and verified well enough to
construct a changes payload. That strongly suggests the failure happened after
verification, during actual patch execution.
This is the key reason I do not think the main issue is grammar parsing.
What looks more likely
Current open-source Codex still routes apply_patch through a verify-then-delegate model:
- the patch is parsed and verified first
- then the runtime delegates execution by re-invoking Codex itself using:
codex --codex-run-as-apply-patch
Relevant source files:
- codex-rs/core/src/tools/handlers/apply_patch.rs
- codex-rs/core/src/tools/runtimes/apply_patch.rs
- codex-rs/arg0/src/lib.rs
- codex-rs/apply-patch/src/parser.rs
- codex-rs/apply-patch/src/lib.rs
This means apply_patch is more sensitive than a normal file write to issues in:
- executable path resolution
- self-reexec program path
- app-server / exec-server environment handoff
- sandbox command construction
- cwd/path canonicalization
- wrapper / dispatch behavior
If any of those drift, apply_patch can still pass verification and then fail later with
ENOENT during execution.
Why 0.117.0 is suspicious
The timing lines up with two important upstream changes:
- App-server TUI enabled by default
PR: Enabletui_app_serverfeature by default #15661 “Enable tui_app_server feature by default”
Enabletui_app_serverfeature by default #15661 - Exec/environment refactors just before that
PR: Move environment abstraction into exec server #15125 “Move environment abstraction into exec server”
Move environment abstraction into exec server #15125
PR: #15232 “Refactor ExecServer filesystem split between local and remote”
#15232
PR: #15233 “Split exec process into local and remote implementations”
#15233
Those changes are much closer to the observed symptom than any parser-specific change.
What I did not find
I did not find evidence that 0.117.0 introduced a major parser tightening for apply_patch.
In fact, the parser still appears lenient:
- PARSE_IN_STRICT_MODE = false
- earlier upstream changes even relaxed patch marker handling rather than tightening it
I also checked a recent apply_patch-related PR in the 0.117 window:
- PR Add apply_patch code mode result #15100 “Add apply_patch code mode result”
Add apply_patch code mode result #15100
That change affects result surfacing/output behavior, not parser semantics or patch file
application logic.
Important session-specific observation
In the target session, some failing patch attempts were followed by shell checks showing
that the target file still existed and was visible from the expected path.
That makes the repeated ENOENT even more suspicious as an execution-path problem rather
than a missing target file problem.
There was also visible runtime surface drift in the same session:
- old Python-oriented skill entry surfaces were still being read
- new TypeScript-oriented runtime files were being generated
I do not think the TypeScript migration itself is the root cause, but it may have
increased the chance of exposing an execution-path bug.
Likely root-cause direction
My current best hypothesis is:
apply_patch became more failure-prone in 0.117.0 because the runtime path that delegates
verified patches into actual execution changed, likely due to app-server / exec-server
default-path changes, and not because patch syntax validation became stricter.
- whether sandbox/path canonicalization causes the delegated executable or working
directory to become unresolved
Short conclusion
This looks like an apply_patch execution/runtime regression, not primarily a parser
regression.
The strongest signal is that the session contains repeated post-verification ENOENT
failures, while current open-source parser behavior remains broadly lenient and unchanged
in the ways that would explain this pattern.
What steps can reproduce the bug?
Uploaded thread: 019d33a5-9976-73f3-b05f-6fb0802c5c13
Codex issue session id: "019d310c-4996-7d52-b3e6-67a59ad0d0ad"
What is the expected behavior?
No response
Additional information
No response