{"record":{"id":"d1369e0414ca4f0e","repo":"Aider-AI/aider","slug":"invalid-add-file-line-missing-line","errorCode":null,"errorMessage":"Invalid Add File line (missing '+'): {line}","messagePattern":"Invalid Add File line \\(missing '\\+'\\): (.+?)","errorType":"exception","errorClass":"DiffError","httpStatus":null,"severity":"error","filePath":"aider/coders/patch_coder.py","lineNumber":540,"sourceCode":"            # Stop if we hit another action or end marker\n            if norm_line.startswith(\n                (\n                    \"*** End Patch\",\n                    \"*** Update File:\",\n                    \"*** Delete File:\",\n                    \"*** Add File:\",\n                )\n            ):\n                break\n\n            # Expect lines to start with '+'\n            if not line.startswith(\"+\"):\n                # Tolerate blank lines? Or require '+'? Reference implies '+' required.\n                if norm_line.strip() == \"\":\n                    # Treat blank line as adding a blank line\n                    added_lines.append(\"\")\n                else:\n                    raise DiffError(f\"Invalid Add File line (missing '+'): {line}\")\n            else:\n                added_lines.append(line[1:])  # Strip leading '+'\n\n            index += 1\n\n        action = PatchAction(type=ActionType.ADD, path=\"\", new_content=\"\\n\".join(added_lines))\n        return action, index\n\n    def apply_edits(self, edits: List[PatchAction]):\n        \"\"\"\n        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]]","sourceCodeStart":522,"sourceCodeEnd":558,"githubUrl":"https://github.com/Aider-AI/aider/blob/5dc9490bb35f9729ef2c95d00a19ccd30c26339c/aider/coders/patch_coder.py#L522-L558","documentation":"While parsing the body of an '*** Add File:' block, a non-blank line did not start with '+'. Add-file bodies require every content line to be prefixed with '+' (blank lines are tolerated as blank content). Any other leading character is rejected.","triggerScenarios":"Model emits raw file content without '+' prefixes inside an Add File block; a '-' or ' ' diff-style line leaks in; a nested '***' header terminates the block and the stray line follows.","commonSituations":"Model mixes unified-diff habits into the patch format; long generated files where the model forgets prefixes partway; hand-written patches pasted from editors.","solutions":["Prefix every content line in the Add File block with '+'","Regenerate — aider's retry loop typically gets the model to fix prefix mistakes","Validate add-block lines with a linter/regex ('^($|\\+|\\*\\*\\*)') before applying"],"exampleFix":"// before\n*** Add File: a.txt\nhello\n\n// after\n*** Add File: a.txt\n+hello\n","handlingStrategy":"validation","validationCode":"def add_body_prefixed(patch_text: str) -> bool:\n    in_add = False\n    for line in patch_text.splitlines():\n        if line.startswith(\"*** Add File: \"):\n            in_add = True\n        elif line.startswith(\"*** \"):\n            in_add = False\n        elif in_add and line and not line.startswith(\"+\"):\n            return False\n    return True","typeGuard":null,"tryCatchPattern":"try:\n    edits = coder.get_edits(reply)\nexcept DiffError as e:\n    if \"Invalid Add File line (missing '+')\" in str(e):\n        reply = auto_prefix_add_body(reply)\n        edits = coder.get_edits(reply)\n    else:\n        raise","preventionTips":["State in the prompt that Add File content lines must each start with '+'","Reject patches whose add blocks contain raw (unprefixed) content","Beware models mixing unified-diff '-'/' ' conventions into patch format"],"tags":["aider","patch","add-file","parsing"],"backgroundTag":null,"analyzedSha":"5dc9490bb35f9729ef2c95d00a19ccd30c26339c","analyzedAt":"2026-08-15T05:40:10.498Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}