{"record":{"id":"e4a518a24d09d93e","repo":"Aider-AI/aider","slug":"path-mismatch-applying-patch-near-line-chunk-s","errorCode":null,"errorMessage":"{path}: Mismatch applying patch near line {chunk_start_index + 1}.\nExpected lines to remove:\n{expected_str}\nFound lines in file:\n{actual_str}","messagePattern":"(.+?): Mismatch applying patch near line (.+?)\\.\nExpected lines to remove:\n(.+?)\nFound lines in file:\n(.+?)","errorType":"exception","errorClass":"DiffError","httpStatus":null,"severity":"error","filePath":"aider/coders/patch_coder.py","lineNumber":687,"sourceCode":"\n            # Add lines from original file between the last chunk and this one\n            dest_lines.extend(orig_lines[current_orig_line_idx:chunk_start_index])\n\n            # Verify that the lines to be deleted actually match the original file content\n            # (The parser should have used find_context, but double-check here)\n            num_del = len(chunk.del_lines)\n            actual_deleted_lines = orig_lines[chunk_start_index : chunk_start_index + num_del]\n\n            # Use the same normalization as find_context_core for comparison robustness\n            norm_chunk_del = [_norm(s).strip() for s in chunk.del_lines]\n            norm_actual_del = [_norm(s).strip() for s in actual_deleted_lines]\n\n            if norm_chunk_del != norm_actual_del:\n                # This indicates the context matching failed or the file changed since parsing\n                # Provide detailed error message\n                expected_str = \"\\n\".join(f\"- {s}\" for s in chunk.del_lines)\n                actual_str = \"\\n\".join(f\"  {s}\" for s in actual_deleted_lines)\n                raise DiffError(\n                    f\"{path}: Mismatch applying patch near line {chunk_start_index + 1}.\\n\"\n                    f\"Expected lines to remove:\\n{expected_str}\\n\"\n                    f\"Found lines in file:\\n{actual_str}\"\n                )\n\n            # Add the inserted lines from the chunk\n            dest_lines.extend(chunk.ins_lines)\n\n            # Advance the original line index past the lines processed (deleted lines)\n            current_orig_line_idx = chunk_start_index + num_del\n\n        # Add any remaining lines from the original file after the last chunk\n        dest_lines.extend(orig_lines[current_orig_line_idx:])\n\n        # Join lines and ensure a single trailing newline\n        result = \"\\n\".join(dest_lines)\n        if result or orig_lines:  # Add newline unless result is empty and original was empty\n            result += \"\\n\"","sourceCodeStart":669,"sourceCodeEnd":705,"githubUrl":"https://github.com/Aider-AI/aider/blob/5dc9490bb35f9729ef2c95d00a19ccd30c26339c/aider/coders/patch_coder.py#L669-L705","documentation":"Verification failure while applying a chunk: the lines the patch wants to delete at chunk_start_index do not match the file's actual lines, after whitespace-normalizing both. This is the apply-time double-check of the parser's context match — usually the file changed between parse and apply.","triggerScenarios":"File on disk modified after parsing (format-on-save, linter, another process); chunk.del_lines that never matched due to parser fuzz tolerance; encoding differences making normalized comparison fail.","commonSituations":"IDE auto-format on save racing the apply; two aider sessions on the same file; applying a stale patch after a git pull.","solutions":["Re-read the file and regenerate the patch from its current content","Disable/reconcile auto-formatting processes that touch the file during apply","Diff the 'Expected lines to remove' vs 'Found lines in file' in the message to see exactly what drifted, then hand-fix the patch or file"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"def chunk_de_lines_match(chunks, file_lines) -> list[int]:\n    bad = []\n    for c in sorted(chunks, key=lambda c: c.orig_index):\n        actual = [s.strip() for s in file_lines[c.orig_index:c.orig_index + len(c.del_lines)]]\n        if [s.strip() for s in c.del_lines] != actual:\n            bad.append(c.orig_index)\n    return bad  # empty == safe to apply","typeGuard":null,"tryCatchPattern":"try:\n    coder.apply_edits(edits)\nexcept ValueError as e:\n    if \"Mismatch applying patch\" in str(e):\n        # re-read file and regenerate patch from fresh content\n        content = read_file(action_path)\n        edits = coder.get_edits(regenerate_patch_for(content))\n        coder.apply_edits(edits)\n    else:\n        raise","preventionTips":["Re-read files right before applying when anything might have touched them (formatters, other sessions)","Diff the expected/found lines in the message to identify the drift source","Avoid running two edit tools on the same file concurrently"],"tags":["aider","patch","chunks","file-drift"],"backgroundTag":null,"analyzedSha":"5dc9490bb35f9729ef2c95d00a19ccd30c26339c","analyzedAt":"2026-08-15T05:40:10.498Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}