Codex Patch Conflicts With Existing Code

"Patch hunk failed to apply" — file moved between Codex's read and write. Refresh state, normalize whitespace, or split the patch.

Codex generates a patch and the apply step fails: error: patch failed: src/utils.ts:42 / Hunk #1 FAILED at 42. Or the patch applies but leaves <<<<<<< conflict markers in your file. Codex insists the diff is correct; git insists the file is different. Both are right — what Codex read and what’s on disk now are no longer the same.

Patch conflicts are nearly always state-drift between read and write. Fix the drift, not the patch. The four mechanisms: file changed mid-session, auto-formatter ran on save, CRLF↔LF normalization, or two agents/users editing in parallel.

Common causes

Ordered by hit rate, highest first.

1. File changed between Codex’s read and the patch apply

Codex read utils.ts 30 seconds ago. You then formatted the file in your editor (Prettier on save). Now the line numbers in the patch don’t match.

How to spot it: git status shows the file as modified at a different timestamp than expected. Or git diff between Codex’s read time and now reveals the unexpected changes.

2. Auto-formatter ran after Codex read, before patch apply

VS Code’s “format on save” is the silent culprit. You glanced at the file (which triggered nothing), but Prettier reformatted on focus-change save. Codex’s line-anchored patch now misses by 2 lines.

How to spot it: Disable format-on-save ("editor.formatOnSave": false), have Codex re-read + regenerate the patch. If it now applies, format-on-save was it.

3. Whitespace / line-ending mismatch (CRLF vs LF)

Repo cloned on Windows with core.autocrlf=true produces CRLF locally; Codex returns LF in patches. Every line differs in invisible whitespace; git refuses to apply.

How to spot it: git config core.autocrlf shows true. Or file src/utils.ts reports “CRLF line terminators.” Patches Codex generates are LF, mismatched.

4. Codex’s read was from a different commit than apply target

You started the session on feature/billing, switched to main while Codex was thinking, asked it to apply the patch on the new branch. The patch was for the old commit; the new branch doesn’t have those lines.

How to spot it: git log --oneline -5 for both branches. If they diverge before the file Codex read, the patch is for a different past.

5. Two agents (or agent + you) edited the file in parallel

Claude Code and Codex were both told to update utils.ts. One finished first; the other’s patch is based on the pre-edit state and now conflicts.

How to spot it: git log src/utils.ts --oneline shows multiple recent commits or git status shows uncommitted changes you didn’t make. Coordination failure.

6. Codex generated a fuzzy / abbreviated diff

Some Codex modes return prose-style diffs with // ... placeholders rather than literal full hunks. The apply step can’t reconstruct what // ... should be, so it fails or guesses wrong.

How to spot it: The patch text contains literal // ... or … (unchanged) markers. Force Codex to return full hunks with --no-elide style instruction.

Shortest path to fix

Ordered by ROI. Step 1 alone fixes 60% of conflicts.

Step 1: Stop, check current state, regenerate

When a hunk fails:

# 1. See actual state
git status
git diff src/utils.ts

# 2. If working tree is dirty with surprises, identify the source
git log --oneline -5 src/utils.ts

Then prompt Codex:

The patch failed to apply. Current state of `src/utils.ts`:
[paste the actual content or first 50 lines]

Re-read this file fresh and regenerate the patch.

Don’t force-apply a stale patch.

Step 2: Disable auto-format during agent sessions

VS Code settings:

{
  "editor.formatOnSave": false,
  "editor.formatOnPaste": false,
  "editor.codeActionsOnSave": {}
}

Or per-workspace .vscode/settings.json. Re-enable after the agent finishes (and run pnpm format once to normalize).

Step 3: Normalize line endings repo-wide

In .gitattributes:

* text=auto eol=lf
*.bat text eol=crlf
*.png binary
*.jpg binary

Then:

git rm --cached -r .
git reset --hard

Now everyone’s checkouts are LF; Codex patches apply cleanly.

For Windows devs, git config --global core.autocrlf input (not true).

Step 4: Commit before agent runs, agent commits before next runs

Single-agent discipline:

1. `git status` clean before starting agent.
2. Agent edits + tests.
3. `git add -A && git commit -m "agent: <task>"` before starting next session.

For multi-agent workflows, treat shared files as exclusive — only one agent touches each file at a time, coordinated via the task tracker or a CODEOWNERS-style claim.

Step 5: Force full-hunk diffs, not elided ones

In the prompt:

Return the full patch text — every line of every modified function.
Do NOT use `// ...` placeholders, `// (unchanged)` markers, or elision.
The diff must be apply-clean against the current file.

For Codex modes that auto-apply, this is usually default; for “return a diff for me to apply manually,” explicit instruction prevents elision.

Step 6: For persistent conflicts, split the patch

If a single large patch keeps failing, split into smaller atomic patches:

Don't generate one big patch. Instead:
1. Add the new `validate()` method — return that patch.
2. After I apply, update the call sites — return that patch.
3. After I apply, update the tests — return that patch.

Each patch should touch at most 3 files.

Smaller patches have smaller “blast radius” for conflicts and recover faster when something drifts.

Prevention

  • Normalize line endings via .gitattributes (* text=auto eol=lf) once and forget it
  • Disable editor.formatOnSave during agent sessions; format once at the end as a deliberate step
  • Treat shared files as exclusive — one agent at a time, coordinated through commits
  • Always demand full-hunk diffs from Codex; elided patches cause more conflicts than they save tokens
  • Commit before every agent run and after; clean state in / clean state out
  • For large refactors, split into a chain of small patches rather than one mega-patch

Tags: #Codex #Coding agent #Troubleshooting #Debug #Patch conflicts