{"record":{"id":"8e7619091690853e","repo":"Aider-AI/aider","slug":"delete-file-action-missing-path","errorCode":null,"errorMessage":"Delete File action missing path.","messagePattern":"Delete File action missing path\\.","errorType":"exception","errorClass":"DiffError","httpStatus":null,"severity":"error","filePath":"aider/coders/patch_coder.py","lineNumber":361,"sourceCode":"                        existing_action.move_path = move_to\n                    fuzz_accumulator += fuzz\n                else:\n                    # First UPDATE block for this file\n                    action, index, fuzz = self._parse_update_file_sections(\n                        lines, index, file_content\n                    )\n                    action.path = path\n                    action.move_path = move_to\n                    patch.actions[path] = action\n                    fuzz_accumulator += fuzz\n                continue\n\n            # ---------- DELETE ---------- #\n            elif norm_line.startswith(\"*** Delete File: \"):\n                path = norm_line[len(\"*** Delete File: \") :].strip()\n                index += 1\n                if not path:\n                    raise DiffError(\"Delete File action missing path.\")\n                existing_action = patch.actions.get(path)\n                if existing_action:\n                    if existing_action.type == ActionType.DELETE:\n                        # Duplicate delete – ignore the extra block\n                        self.io.tool_warning(f\"Duplicate delete action for file: {path} ignored.\")\n                        continue\n                    else:\n                        raise DiffError(f\"Conflicting actions for file: {path}\")\n                if path not in current_files:\n                    raise DiffError(\n                        f\"Delete File Error - file not found: {path}\"\n                    )  # Check against known files\n\n                patch.actions[path] = PatchAction(type=ActionType.DELETE, path=path)\n                continue\n\n            # ---------- ADD ---------- #\n            elif norm_line.startswith(\"*** Add File: \"):","sourceCodeStart":343,"sourceCodeEnd":379,"githubUrl":"https://github.com/Aider-AI/aider/blob/5dc9490bb35f9729ef2c95d00a19ccd30c26339c/aider/coders/patch_coder.py#L343-L379","documentation":"Thrown by PatchCoder's patch parser when a '*** Delete File:' header line has no path after the colon (empty or whitespace-only). The parser strips the prefix and checks that a non-empty path remains before creating a DELETE PatchAction. It signals malformed model output rather than a filesystem problem.","triggerScenarios":"A model emits '*** Delete File: ' with nothing after it (or trailing spaces only) inside a patch block fed to PatchCoder.get_edits/parse. Calling the coder with a hand-written patch that truncates the header also triggers it.","commonSituations":"LLM responses truncated by token limits mid-header; copy-pasted patches that lose the filename; prompts that fail to show a valid Delete File example so the model invents an empty one.","solutions":["Regenerate the patch ensuring every '*** Delete File: <path>' header includes a real relative path","If driving the parser programmatically, validate patch headers with a regex before calling the coder","Catch DiffError and retry the edit request with the offending patch text echoed back so the model can self-correct"],"exampleFix":"// before\n*** Delete File: \n\n// after\n*** Delete File: src/old_module.py\n","handlingStrategy":"validation","validationCode":"import re\n\ndef patch_delete_headers_valid(patch_text: str) -> bool:\n    for line in patch_text.splitlines():\n        if line.startswith(\"*** Delete File: \"):\n            if not line[len(\"*** Delete File: \"):].strip():\n                return False\n    return True","typeGuard":null,"tryCatchPattern":"from aider.coders.patch_coder import PatchCoder\ntry:\n    edits = coder.get_edits(reply)\nexcept DiffError as e:\n    if \"Delete File action missing path\" in str(e):\n        reply = regenerate_patch(reply)  # ask model to fix header\n        edits = coder.get_edits(reply)\n    else:\n        raise","preventionTips":["Include a valid Delete File example in the system prompt so the model copies the shape","Ensure max output tokens is high enough that patch headers are not truncated","Pre-validate all '*** ' headers with a regex before parsing"],"tags":["aider","patch","parsing","llm-output"],"backgroundTag":null,"analyzedSha":"5dc9490bb35f9729ef2c95d00a19ccd30c26339c","analyzedAt":"2026-08-15T05:40:10.498Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}