Aider-AI/aider · error · DiffError

ADD Error: File already exists: {action.path}

Error message

ADD Error: File already exists: {action.path}

What it means

Application-time check in apply_edits(): an ADD action targets a path that already exists on disk. The parser can't fully check existence (it only sees chat files), so the guard runs just before writing and aborts the write to avoid clobbering an existing file.

Source

Thrown at aider/coders/patch_coder.py:569

        Applies the parsed PatchActions to the corresponding files.
        """
        if not edits:
            return

        # Group edits by original path? Not strictly needed if processed sequentially.

        # Edits are now List[Tuple[str, PatchAction]]
        for _path_tuple_element, action in edits:
            # action is the PatchAction object
            # action.path is the canonical path within the action logic
            full_path = self.abs_root_path(action.path)
            path_obj = pathlib.Path(full_path)

            try:
                if action.type == ActionType.ADD:
                    # Check existence *before* writing
                    if path_obj.exists():
                        raise DiffError(f"ADD Error: File already exists: {action.path}")
                    if action.new_content is None:
                        # Parser should ensure this doesn't happen
                        raise DiffError(f"ADD change for {action.path} has no content")

                    self.io.tool_output(f"Adding {action.path}")
                    path_obj.parent.mkdir(parents=True, exist_ok=True)
                    # Ensure single trailing newline, matching reference behavior
                    content_to_write = action.new_content
                    if not content_to_write.endswith("\n"):
                        content_to_write += "\n"
                    self.io.write_text(full_path, content_to_write)

                elif action.type == ActionType.DELETE:
                    self.io.tool_output(f"Deleting {action.path}")
                    if not path_obj.exists():
                        self.io.tool_warning(
                            f"DELETE Warning: File not found, skipping: {action.path}"
                        )

View on GitHub (pinned to 5dc9490bb3)

Solutions

  1. If the file should be replaced, delete or rename it first (or use an UPDATE action instead of ADD)
  2. If the add is a mistake, drop the Add block from the patch
  3. Ensure the target file is in chat context so the model updates rather than adds it

Example fix

# before
*** Add File: existing.py
+...

# after: update instead of add
*** Update File: existing.py
@@ ... @@
Defensive patterns

Strategy: validation

Validate before calling

import os

def add_targets_missing(actions) -> list[str]:
    return [a.path for a in actions
            if a.type.name == "ADD" and os.path.exists(os.path.join(ROOT, a.path))]

Try / catch

try:
    coder.apply_edits(edits)
except ValueError as e:
    if "File already exists" in str(e):
        path = str(e).split("File already exists: ", 1)[-1].strip()
        os.rename(path, path + ".bak")  # or convert ADD to UPDATE
        coder.apply_edits(edits)
    else:
        raise

Prevention

When it happens

Trigger: The file was created (by another tool, a prior apply, or another patch action) between parse and apply; the model adds a file that actually exists but was never in chat; the same patch applied twice.

Common situations: Re-running an /apply after a partial success; files created outside aider concurrently; model unaware a file exists because it wasn't added to chat.

Related errors


AI-assisted analysis of Aider-AI/aider@5dc9490bb3 (2026-08-15). Data as JSON: /api/errors/b33e7bef600622b1. Report an issue: GitHub.