{"record":{"id":"b33e7bef600622b1","repo":"Aider-AI/aider","slug":"add-error-file-already-exists-action-path","errorCode":null,"errorMessage":"ADD Error: File already exists: {action.path}","messagePattern":"ADD Error: File already exists: (.+?)","errorType":"exception","errorClass":"DiffError","httpStatus":null,"severity":"error","filePath":"aider/coders/patch_coder.py","lineNumber":569,"sourceCode":"        Applies the parsed PatchActions to the corresponding files.\n        \"\"\"\n        if not edits:\n            return\n\n        # Group edits by original path? Not strictly needed if processed sequentially.\n\n        # Edits are now List[Tuple[str, PatchAction]]\n        for _path_tuple_element, action in edits:\n            # action is the PatchAction object\n            # action.path is the canonical path within the action logic\n            full_path = self.abs_root_path(action.path)\n            path_obj = pathlib.Path(full_path)\n\n            try:\n                if action.type == ActionType.ADD:\n                    # Check existence *before* writing\n                    if path_obj.exists():\n                        raise DiffError(f\"ADD Error: File already exists: {action.path}\")\n                    if action.new_content is None:\n                        # Parser should ensure this doesn't happen\n                        raise DiffError(f\"ADD change for {action.path} has no content\")\n\n                    self.io.tool_output(f\"Adding {action.path}\")\n                    path_obj.parent.mkdir(parents=True, exist_ok=True)\n                    # Ensure single trailing newline, matching reference behavior\n                    content_to_write = action.new_content\n                    if not content_to_write.endswith(\"\\n\"):\n                        content_to_write += \"\\n\"\n                    self.io.write_text(full_path, content_to_write)\n\n                elif action.type == ActionType.DELETE:\n                    self.io.tool_output(f\"Deleting {action.path}\")\n                    if not path_obj.exists():\n                        self.io.tool_warning(\n                            f\"DELETE Warning: File not found, skipping: {action.path}\"\n                        )","sourceCodeStart":551,"sourceCodeEnd":587,"githubUrl":"https://github.com/Aider-AI/aider/blob/5dc9490bb35f9729ef2c95d00a19ccd30c26339c/aider/coders/patch_coder.py#L551-L587","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["If the file should be replaced, delete or rename it first (or use an UPDATE action instead of ADD)","If the add is a mistake, drop the Add block from the patch","Ensure the target file is in chat context so the model updates rather than adds it"],"exampleFix":"# before\n*** Add File: existing.py\n+...\n\n# after: update instead of add\n*** Update File: existing.py\n@@ ... @@\n","handlingStrategy":"validation","validationCode":"import os\n\ndef add_targets_missing(actions) -> list[str]:\n    return [a.path for a in actions\n            if a.type.name == \"ADD\" and os.path.exists(os.path.join(ROOT, a.path))]","typeGuard":null,"tryCatchPattern":"try:\n    coder.apply_edits(edits)\nexcept ValueError as e:\n    if \"File already exists\" in str(e):\n        path = str(e).split(\"File already exists: \", 1)[-1].strip()\n        os.rename(path, path + \".bak\")  # or convert ADD to UPDATE\n        coder.apply_edits(edits)\n    else:\n        raise","preventionTips":["Check git status / filesystem before re-applying a patch to avoid double-application","Keep target files in chat so the model updates rather than adds them","Convert add-to-update when the file already exists and you want replacement semantics"],"tags":["aider","patch","add","file-exists"],"backgroundTag":null,"analyzedSha":"5dc9490bb35f9729ef2c95d00a19ccd30c26339c","analyzedAt":"2026-08-15T05:40:10.498Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}