How to Resolve Merge Conflicts Between Coding Agents
A contract-first workflow for resolving textual, semantic, generated-output, migration, and authority conflicts between Claude Code, Codex, Cursor, and other coding agents.
How to Resolve Merge Conflicts Between Coding Agents
Resolving a merge conflict between coding agents means reconstructing the intent and authority behind both branches, choosing the accepted contract, and proving the combined behavior—not merely deleting Git conflict markers.
Claude Code can change an API while Codex updates a client. Cursor can edit the same component while another agent changes its design-system contract. Git may report a conflict, but the markers are only the visible symptom. The real disagreement may be about ownership, behavior, generated output, migration order, or which instruction was authoritative.
A reliable conflict-resolution workflow answers five questions:
- What outcome did each branch intend to produce?
- Which exact base and assumptions did each agent use?
- What kind of conflict occurred?
- Which repository source has authority over the disputed behavior?
- What executable evidence proves the resolution?
This guide focuses on that repair loop. For the broader sequence around it, start with How to Integrate Changes from Multiple Coding Agents and Git Worktrees for Multiple Coding Agents.
Why conflict markers are not the conflict
Git compares text. Your system depends on contracts.
Two branches can edit the same lines for unrelated reasons, producing a noisy textual conflict that is easy to resolve. More dangerously, they can edit different files while implementing incompatible assumptions:
agent/api
changes: openapi/avatar.yaml
new behavior: 422 response with field_errors[]
agent/web
changes: src/avatar/upload.ts
assumed behavior: 400 response with message
Git result: clean merge
Runtime result: broken error handling
The merge is textually clean and semantically wrong.
Treat every agent branch as a bundle of claims:
| Branch claim | Conflict review asks |
|---|---|
| intended outcome | Do both branches still serve the same user-visible goal? |
| exact base | Did either branch start from stale repository state? |
| changed contracts | Which branch produces the accepted schema or behavior? |
| implementation | Are the edits compatible with that contract? |
| evidence | Which checks passed, and what did they actually prove? |
| omissions | Which shared boundaries were never tested? |
| authority | Which file, decision, or owner decides the disagreement? |
Conflict resolution starts by reconstructing these claims before editing the candidate.
The contract-first conflict loop
The loop deliberately returns to a source branch or canonical controller. Fixing only the integration branch leaves the original checkpoint and its handoff wrong, so the next integration repeats the same failure.
1. Freeze both sides before editing
Do not resolve a conflict while one agent is still writing. Freeze each branch at a stable commit and record its base.
git fetch origin
git rev-parse agent/api
git rev-parse agent/web
git merge-base agent/api origin/main
git merge-base agent/web origin/main
git diff --check origin/main...agent/api
git diff --check origin/main...agent/web
git status --short
For each side, capture:
## Conflict input
- Task: avatar API errors
- Branch: `agent/api`
- Commit: `4d31...`
- Base: `origin/main@a13f...`
- Outcome: return field-level validation errors
- Produces: OpenAPI response schema and server behavior
- Evidence: API contract suite — PASS, 18 tests
- Not run: generated clients and browser flow
- Residual risk: consumers may still expect the old error shape
If a tree is dirty, ask the agent to create a coherent checkpoint or explicitly name the uncommitted paths. An active workspace is not a reproducible conflict input.
2. Reconstruct intent before choosing lines
Conflict tools present versions of files. They do not present the reason each version exists.
Before resolving, the integrator should be able to state:
- the user-visible outcome of each branch;
- the exact contract each branch produces or consumes;
- the repository instruction or decision each agent followed;
- whether either branch used a stale base;
- the tests that passed and the surfaces they did not cover;
- the owner or canonical source for the disputed behavior.
A compact reconstruction table helps:
| Question | API branch | Web branch |
|---|---|---|
| outcome | structured validation errors | render upload errors inline |
| produces | OpenAPI schema + server behavior | UI behavior |
| consumes | product decision 0042 | TypeScript client + public errors |
| base | a13f... | a13f... |
| proof | API contract tests | component tests with fixture |
| gap | no generated-client check | fixture is hand-authored |
| authority | openapi/avatar.yaml | consumes API authority |
The resolution is now clear: accept the authoritative API contract, regenerate the client, and adapt the UI. Choosing “ours” or “theirs” by line count would hide the dependency.
3. Classify the conflict
Different conflict classes require different repairs. Use at least these six.
Textual conflict
Both branches changed overlapping lines but may still agree on behavior.
Repair: reconstruct both intents, produce one coherent implementation, and rerun checks covering the affected code. Do not assume a small conflict is low-risk; one changed condition can alter behavior.
Contract conflict
Branches disagree about a schema, public function, CLI, event, configuration key, persisted format, or error shape.
Repair: identify the contract owner and canonical source, accept one explicit version, adapt every consumer, and run compatibility checks. Do not average two contracts into an undocumented third option.
Generated-output conflict
Generated files differ because branches used different schema revisions, templates, lockfiles, or generator versions.
Repair: resolve the source inputs and tool version, discard conflicting derived output, regenerate, and verify the generated tree is clean on a second run.
Behavior conflict
Files merge without markers but the combined runtime behavior is wrong. Middleware order, fallback precedence, shared state, or error handling may interact.
Repair: add a failing boundary or outcome test, decide the accepted behavior, repair the owning implementation, and keep the test as durable evidence.
Migration conflict
Branches introduce database, configuration, or persisted-state transitions that are individually valid but unsafe in combination or order.
Repair: define forward order, compatibility window, retry behavior, and rollback. Test from realistic old state through the combined migration and back where rollback is supported.
Authority conflict
Agents followed contradictory instructions, decisions, or ownership claims.
Repair: stop editing code. Resolve the canonical instruction or decision first, then replay the affected work against one authority. Code cannot decide which governance source should have won.
Use a resolution matrix:
| Conflict class | First authority to inspect | Required proof |
|---|---|---|
| textual | behavior owner + nearby tests | focused tests and diff review |
| contract | schema/spec/API owner | producer-consumer compatibility |
| generated output | source schema/template + pinned tool | deterministic regeneration |
| behavior | product invariant + runtime owner | reproducer and outcome test |
| migration | persisted format + migration journal | forward, retry, and rollback proof |
| authority | canonical instructions/decision record | clean-session reconstruction |
Classification prevents the conflict editor from becoming the decision system.
4. Create a disposable integration candidate
Resolve conflicts on a dedicated candidate from an exact clean base. Keep worker branches intact.
git switch -c integration/avatar-errors origin/main
git rev-parse HEAD
git merge --no-commit --no-ff agent/api
# Resolve and validate the producer boundary before continuing.
Record the plan before editing:
## Conflict-resolution plan
- Base: `origin/main@a13f...`
- Candidate: `integration/avatar-errors`
- Inputs: `agent/api@4d31...`, `agent/web@73af...`
- Accepted authority: `openapi/avatar.yaml`
- Conflict owner: integration lead
- Contract owner: API maintainer
- Gate 1: API contract suite
- Gate 2: regenerate client twice; second run clean
- Gate 3: web typecheck and component tests
- Final gate: browser upload-error smoke flow
- Rollback checkpoint: clean base `a13f...`
A dedicated candidate makes failed experiments cheap. It also prevents conflict edits from leaking into main or into a worker branch whose original claim must remain inspectable.
5. Resolve the authoritative source first
The safest order is:
- decide the accepted behavior;
- resolve its canonical source;
- update or regenerate derived artifacts;
- adapt downstream consumers;
- validate each dependency boundary;
- prove the combined outcome.
For the avatar example:
# After accepting the final OpenAPI contract:
scripts/validate-api avatar
scripts/generate-clients
scripts/check-generated-clean
scripts/validate-clients avatar
scripts/validate-web avatar
scripts/smoke-avatar-errors
git status --short
Run the generator twice if determinism matters. The first run updates derived files; the second should produce no diff.
scripts/generate-clients
git diff --exit-code -- generated/
Never use the generated file as the place where two agents negotiate the contract. The next generation run will erase that negotiation.
6. Treat repository instructions as executable authority
Parallel agents frequently conflict because scopes were ambiguous, not because Git was difficult.
A repository-level rule can make authority explicit:
## Shared contract ownership
- `openapi/**` is authoritative for public HTTP schemas.
- `clients/generated/**` is derived; never edit it by hand.
- API-contract tasks integrate before client and UI consumers.
- The API owner approves contract conflicts.
- Every accepted contract change must pass `scripts/check-api-contract`.
- Every generated-client resolution must pass two clean generation runs.
Keep root instructions short and route details to a runbook or script. The goal is not more prose. The goal is that a clean agent session can discover the same authority and run the same proof.
See Repository Harness Patterns for the broader source-of-truth and validation-contract patterns.
7. Validate the conflict boundary and final outcome
A conflict-resolution test should cover the disagreement, not just the edited files.
| Proof level | Question | Example |
|---|---|---|
| source | Is the accepted contract internally valid? | OpenAPI validation |
| producer-consumer | Do derived clients match the source? | regenerate + compile |
| local behavior | Does each affected subsystem work? | API and component suites |
| combined behavior | Does the real flow work across boundaries? | upload-error smoke test |
| reproducibility | Did tools leave unexplained changes? | clean git status --short |
| recovery | Can a failed transition retry or roll back? | migration recovery probe |
A useful final evidence record is:
## Conflict resolution — avatar validation errors
### Inputs
- API: `agent/api@4d31...`
- Web: `agent/web@73af...`
- Base: `origin/main@a13f...`
### Classification
Contract conflict plus generated-output conflict.
### Decision
`openapi/avatar.yaml` owns the response shape. Accepted `422` with
`field_errors[]`; UI fixtures and rendering now consume the generated type.
### Resolution
- accepted API schema from the contract branch;
- regenerated TypeScript and Python clients;
- removed hand-authored UI error fixture;
- adapted rendering to the generated error union.
### Evidence
- API contract suite — PASS, 18 tests
- client generation — PASS, second run clean
- TypeScript client compile — PASS
- web typecheck — PASS
- component suite — PASS, 27 tests
- upload-error smoke — PASS
- `git status --short` — clean
### Omitted
Safari multipart flow; no runner in this environment.
### Durable prevention
Client tasks now record the producer schema commit and prohibit edits under
`clients/generated/**`.
This record is a handoff to code review, release automation, or a clean verification agent.
8. Recover when the resolution is wrong
A failed resolution is expected evidence, not a reason to keep editing until the suite turns green.
Use this recovery sequence:
- preserve the failed candidate commit, logs, and exact command output;
- classify the failed gate;
- identify the owning source or worker branch;
- restore or recreate the candidate from the last known-good checkpoint;
- repair the source branch or canonical instruction;
- update its handoff and evidence;
- replay every downstream gate whose assumptions changed;
- preserve worker branches until final acceptance.
For risky migration or recovery code, inject failures around mutation boundaries and reload persisted state before retrying. A resolution is not recovery-safe if the next process cannot infer what already happened.
Do not delete the evidence-producing failure. Turn it into a regression test, validation script, task-template field, or repository instruction.
9. Prevent the next conflict before cleanup
The final step is not deleting branches. It is repairing the system that allowed ambiguity.
If the conflict began because several workers owned one contract or consumed an undeclared dependency, repair the plan itself. Task Decomposition for Multiple Coding Agents provides the producer-consumer graph, single-owner contract rules, and launch review that prevent the same class of conflict.
Map each conflict to a durable controller:
| Observed conflict | Durable prevention |
|---|---|
| two agents edited the same subsystem | bounded ownership in task envelopes |
| consumer used a guessed schema | producer commit recorded in handoff |
| generated files were hand-merged | generated-path rule + clean regeneration check |
| branches used different bases | exact base required at task start and handoff |
| migrations landed in unsafe order | dependency graph + migration compatibility gate |
| contradictory instructions | one canonical authority map |
| locally green branches failed together | mandatory combined outcome check |
| conflict decision existed only in chat | repository-visible decision record |
A repository that learns from conflicts needs fewer heroic integrators over time.
A copyable coding-agent conflict checklist
# Coding-agent conflict-resolution checklist
## Freeze
- [ ] every branch has a stable commit or named patch
- [ ] exact base revisions are recorded
- [ ] working trees are clean or dirty paths are explicit
- [ ] worker evidence, omissions, and risks are preserved
## Reconstruct
- [ ] intended outcome of each branch is understood
- [ ] produced and consumed contracts are identified
- [ ] stale assumptions are visible
- [ ] authoritative source and owner are named
## Classify
- [ ] textual conflict checked
- [ ] contract conflict checked
- [ ] generated-output conflict checked
- [ ] behavior conflict checked
- [ ] migration conflict checked
- [ ] authority conflict checked
## Resolve
- [ ] dedicated candidate starts from an exact clean base
- [ ] accepted behavior is decided before line edits
- [ ] canonical source is resolved first
- [ ] derived files are regenerated, not hand-merged
- [ ] consumers adapt to the accepted contract
- [ ] decision and rationale are recorded
## Prove
- [ ] focused source checks pass
- [ ] producer-consumer boundary checks pass
- [ ] combined user-visible outcome passes
- [ ] retry or rollback is tested where relevant
- [ ] final working tree is clean
- [ ] omitted checks and residual risks are explicit
## Learn
- [ ] regression evidence is preserved
- [ ] ownership, task, handoff, or validation controller is repaired
- [ ] worker branches remain until acceptance
- [ ] cleanup follows repository retention policy
Common bad resolutions
Taking the newest branch
The newest branch may still consume a stale contract. Recency is not authority.
Taking the largest diff
Line count says nothing about ownership or correctness. A one-line schema change can control thousands of generated lines.
Asking a third agent to “make both versions work”
Without explicit authority, the third agent may invent a compromise that satisfies neither contract. Give it the accepted behavior and proof commands first.
Running only the tests that already passed
Those tests proved isolated branches. Add a check that crosses the disputed boundary and a final user-visible outcome test.
Editing generated files until Git is clean
A clean index can still be unreproducible. Resolve the source, regenerate, and require the next generation run to be clean.
Fixing only the integration branch
The source branch, handoff, or repository rule remains wrong. Repair the controller that produced the conflict.
Deleting worktrees immediately
The combined candidate can still fail review or release proof. Keep recoverable worker state until acceptance.
When parallel work should become serial
Stop adding concurrent writers when:
- the accepted contract is still changing every hour;
- all tasks edit one tightly coupled subsystem;
- no owner can decide the disputed behavior;
- boundary tests do not exist;
- migrations cannot be retried or rolled back safely;
- conflict resolution repeatedly costs more than the saved implementation time.
Serial execution is not a failure of multi-agent engineering. It is the correct response when dependencies are stronger than the available contracts and gates.
Conflict resolution is a repository capability
Merge conflicts between coding agents are not primarily a Git problem. They expose missing task boundaries, source-of-truth maps, ownership, dependency order, validation contracts, or durable decisions.
The durable workflow is straightforward: freeze stable checkpoints, reconstruct intent, classify the conflict, choose the authoritative contract, repair the source, regenerate derived output, prove the combined outcome, and move the lesson back into the repository.
repository-harness provides a starting structure for making task boundaries, authority, validation, checkpoints, and evidence handoffs visible to Claude Code, Codex, Cursor, and other coding agents.
Related pages
- How to Integrate Changes from Multiple Coding Agents
- How to Manage Multiple Coding Agents in One Repository
- Git Worktrees for Multiple Coding Agents
- Coding-Agent Handoff Template
- Repository Harness Patterns
- Coding-Agent Failure Modes
- How to Audit a Repository for Agent-Readiness
- repository-harness on GitHub
FAQ
How should I resolve a merge conflict between coding agents?
Freeze both agent branches at stable commits, reconstruct each branch’s intended outcome and base, classify the conflict, identify the authoritative contract or source, resolve the source rather than only the conflict markers, and rerun focused boundary checks plus combined outcome validation.
Can Git detect every conflict caused by parallel coding agents?
No. Git detects overlapping textual edits, but branches can merge cleanly while disagreeing about schemas, behavior, migrations, generated files, configuration, or repository instructions. These semantic conflicts require contract-aware validation.
Which coding agent should own the conflict resolution?
A designated integrator should own the resolution process. The owner of the affected contract should decide the accepted behavior. The last agent to finish or the agent that touched the most lines should not automatically win.
Should an agent hand-edit generated files during conflict resolution?
No. Resolve the authoritative schema, specification, template, or generator version first, then regenerate the derived files. Hand-merging generated output hides the real disagreement and produces changes that cannot be reproduced.
When should I rebase instead of merge coding-agent branches?
Use the repository’s declared history policy. Rebase can refresh a focused worker branch before integration; merge commits preserve task boundaries and provenance. Neither method resolves semantic disagreement, so contract and outcome checks remain required.
How do I recover from a bad conflict resolution?
Preserve the failed candidate and logs, return to the last known-good integration checkpoint, repair the branch or canonical source that owned the disagreement, update its handoff, and replay the affected integration gates. Keep worker branches until final acceptance.
How can a repository prevent coding-agent merge conflicts?
Declare file and contract ownership, assign bounded task scopes, isolate concurrent writers in worktrees, record exact bases and stable checkpoints, identify producer-consumer dependencies, centralize generated sources, and provide executable validation commands at every shared boundary.