{"record":{"id":"1e05f9b59d45acb3","repo":"Aider-AI/aider","slug":"unknown-or-misplaced-line-while-parsing-patch-li","errorCode":null,"errorMessage":"Unknown or misplaced line while parsing patch: {line}","messagePattern":"Unknown or misplaced line while parsing patch: (.+?)","errorType":"exception","errorClass":"DiffError","httpStatus":null,"severity":"error","filePath":"aider/coders/patch_coder.py","lineNumber":402,"sourceCode":"                if path in patch.actions:\n                    raise DiffError(f\"Duplicate action for file: {path}\")\n                # Check if file exists in the context provided (should not for Add).\n                # Note: We only have needed files, a full check requires FS access.\n                # if path in current_files:\n                #     raise DiffError(f\"Add File Error - file already exists: {path}\")\n\n                action, index = self._parse_add_file_content(lines, index)\n                action.path = path  # Ensure path is set\n                patch.actions[path] = action\n                continue\n\n            # If we are here, the line is unexpected\n            # Allow blank lines between actions\n            if not norm_line.strip():\n                index += 1\n                continue\n\n            raise DiffError(f\"Unknown or misplaced line while parsing patch: {line}\")\n\n        # Check if we consumed the whole input or stopped early\n        # Tolerate missing \"*** End Patch\" if we processed actions\n        # if index < len(lines) and _norm(lines[index-1]) != \"*** End Patch\":\n        #    raise DiffError(\"Patch parsing finished unexpectedly before end of input.\")\n\n        patch.fuzz = fuzz_accumulator\n        return patch\n\n    def _parse_update_file_sections(\n        self, lines: List[str], index: int, file_content: str\n    ) -> Tuple[PatchAction, int, int]:\n        \"\"\"Parses all sections (@@, context, -, +) for a single Update File action.\"\"\"\n        action = PatchAction(type=ActionType.UPDATE, path=\"\")  # Path set by caller\n        orig_lines = file_content.splitlines()  # Use splitlines for consistency\n        current_file_index = 0  # Track position in original file content\n        total_fuzz = 0\n","sourceCodeStart":384,"sourceCodeEnd":420,"githubUrl":"https://github.com/Aider-AI/aider/blob/5dc9490bb35f9729ef2c95d00a19ccd30c26339c/aider/coders/patch_coder.py#L384-L420","documentation":"Catch-all parse error: a line inside the patch body matched none of the recognized action headers (Update/Delete/Add/Move, end-of-file marker, etc.) and was not blank. The parser only skips blank lines between actions; anything else is unexpected at top level.","triggerScenarios":"A context/change line ('+ foo' or ' foo') appearing before any '*** Update File:' header; stray prose from the model inside the patch fence; wrong fence or marker spelling (e.g. '*** update file:'); trailing junk after '*** End Patch'.","commonSituations":"Model chats inside the code block; patch body lines leaked outside their file section; localized marker text or case mismatches; hand-edited patches with typos in the '***' headers.","solutions":["Check the reported line and ensure every non-blank line belongs to a file section started by a valid '*** Update File:'/'*** Add File:'/'*** Delete File:' header","Verify marker spelling and case exactly ('*** Update File:', '*** End Patch')","Move any commentary outside the fence and regenerate the patch"],"exampleFix":"// before\n+import os\n*** Update File: a.py\n*** End Patch\n\n// after\n*** Update File: a.py\n+import os\n*** End Patch\n","handlingStrategy":"try-catch","validationCode":"KNOWN = (\"*** Begin Patch\", \"*** Update File: \", \"*** Delete File: \", \"*** Add File: \", \"*** Move to: \", \"*** End of File\", \"*** End Patch\")\n\ndef top_level_lines_ok(patch_lines: list[str]) -> bool:\n    in_section = False\n    for line in patch_lines:\n        if line.startswith(\"*** \"):\n            in_section = not line.startswith(\"*** End Patch\")\n            continue\n        if not in_section and line.strip():\n            return False\n    return True","typeGuard":null,"tryCatchPattern":"try:\n    edits = coder.get_edits(reply)\nexcept DiffError as e:\n    if \"Unknown or misplaced line\" in str(e):\n        bad = str(e).split(\"parsing patch: \", 1)[-1]\n        reply = regenerate_with_note(reply, f\"Fix this stray line: {bad}\")\n        edits = coder.get_edits(reply)\n    else:\n        raise","preventionTips":["Require the model to output only the patch inside the fence, no prose","Check exact '*** ' marker spelling and casing","Strip trailing chatter after '*** End Patch' before parsing"],"tags":["aider","patch","parsing","malformed-patch"],"backgroundTag":null,"analyzedSha":"5dc9490bb35f9729ef2c95d00a19ccd30c26339c","analyzedAt":"2026-08-15T05:40:10.498Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}