Aider-AI/aider · error · DiffError
Conflicting move targets for file: {path}
Error message
Conflicting move targets for file: {path} What it means
Raised by PatchCoder._parse_patch_text when merging a repeated UPDATE block for the same file: a '*** Move to:' target is given, but the existing action already has a different move_path. A file cannot be renamed to two destinations in one patch.
Source
Thrown at aider/coders/patch_coder.py:342
if path not in current_files:
raise DiffError(f"Update File Error - missing file content for: {path}")
file_content = current_files[path]
existing_action = patch.actions.get(path)
if existing_action is not None:
# Merge additional UPDATE block into the existing one
if existing_action.type != ActionType.UPDATE:
raise DiffError(f"Conflicting actions for file: {path}")
new_action, index, fuzz = self._parse_update_file_sections(
lines, index, file_content
)
existing_action.chunks.extend(new_action.chunks)
if move_to:
if existing_action.move_path and existing_action.move_path != move_to:
raise DiffError(f"Conflicting move targets for file: {path}")
existing_action.move_path = move_to
fuzz_accumulator += fuzz
else:
# First UPDATE block for this file
action, index, fuzz = self._parse_update_file_sections(
lines, index, file_content
)
action.path = path
action.move_path = move_to
patch.actions[path] = action
fuzz_accumulator += fuzz
continue
# ---------- DELETE ---------- #
elif norm_line.startswith("*** Delete File: "):
path = norm_line[len("*** Delete File: ") :].strip()
index += 1
if not path:View on GitHub (pinned to 5dc9490bb3)
Solutions
- Keep a single '*** Move to:' destination per file across the whole patch (or none).
- Consolidate repeated update blocks for the same file into one block.
- If two renames are genuinely needed, they are contradictory — pick one and delete the other.
- Return the error to the model for a corrected, deduplicated patch.
Example fix
# before *** Update File: a.py *** Move to: b.py @@ context *** Update File: a.py *** Move to: c.py @@ context *** End Patch # after *** Update File: a.py *** Move to: b.py @@ context @@ more context *** End Patch
Defensive patterns
Strategy: validation
Validate before calling
from collections import defaultdict
import re
def conflicting_move_targets(patch_text: str) -> dict[str, set[str]]:
current, moves = None, defaultdict(set)
for l in patch_text.splitlines():
s = l.strip()
if s.startswith("*** Update File: "):
current = s[len("*** Update File: "):].strip()
elif s.startswith("*** Move to: ") and current:
moves[current].add(s[len("*** Move to: "):].strip())
return {p: t for p, t in moves.items() if len(t) > 1} # non-empty → pick one target Try / catch
try:
coder.get_edits(patch_text)
except ValueError as e:
if "Conflicting move targets for file:" in str(e):
path = str(e).split("Conflicting move targets for file:")[-1].strip()
patch_text = keep_single_move_target(patch_text, path)
coder.get_edits(patch_text)
else:
raise Prevention
- Emit at most one '*** Move to:' per file across the entire patch; merge repeated update blocks into one.
- When the model changes its mind about a rename, delete the earlier Move-to, don't add a second.
- Lint patches for duplicate move targets before applying.
When it happens
Trigger: Two '*** Update File: path' blocks for the same path, each carrying a '*** Move to:' with a different target — the second merge detects existing_action.move_path != move_to and raises.
Common situations: Model re-deciding the rename mid-patch; duplicated update sections from generation stutter; edits produced by concatenating two independently generated patches.
Related errors
- Move to action missing path.
- Invalid patch line found in update section: {line}
- Invalid line prefix in update section: {line}
- Empty patch section found.
- Error parsing patch content: {e}
AI-assisted analysis of Aider-AI/aider@5dc9490bb3 (2026-08-15).
Data as JSON: /api/errors/cf9dfb3cb38178ef.
Report an issue: GitHub.