Hmbown/CodeWhale · error

patch removal mismatch in {}: expected '{}'

Error message

patch removal mismatch in {}: expected '{}'

What it means

A removal line (`-content`) must equal the file line at the current cursor exactly, and the cursor must be in bounds (eval.rs:730). A mismatch means the file no longer contains the expected line at that position, so the patch aborts before writing.

Source

Thrown at crates/tui/src/eval.rs:730

        match kind {
            " " => {
                let Some(found) = file_lines[cursor..]
                    .iter()
                    .position(|line| line == &content)
                    .map(|offset| cursor + offset)
                else {
                    return Err(anyhow!(
                        "patch context not found in {}: {}",
                        file_path.display(),
                        content
                    ));
                };
                cursor = found + 1;
            }
            "-" => {
                if cursor >= file_lines.len() || file_lines[cursor] != content {
                    return Err(anyhow!(
                        "patch removal mismatch in {}: expected '{}'",
                        file_path.display(),
                        content
                    ));
                }
                file_lines.remove(cursor);
            }
            "+" => {
                file_lines.insert(cursor, content);
                cursor += 1;
            }
            _ => return Err(anyhow!("unsupported patch line: {raw_line}")),
        }
    }

    let mut updated = file_lines.join("\n");
    if had_trailing_newline {
        updated.push('\n');

View on GitHub (pinned to 8880682c63)

Solutions

  1. Regenerate the patch against the file's current content
  2. Verify every `-` line matches current file content exactly before applying
  3. Apply one patch at a time, re-reading between attempts
Defensive patterns

Strategy: retry

Validate before calling

let original: Vec<&str> = std::fs::read_to_string(&file_path)?.lines().collect();
for removal in patch_removal_lines(&patch) {
    anyhow::ensure!(
        original.iter().any(|l| *l == removal),
        "removal target not in file: {removal}"
    );
}

Try / catch

match apply_patch(&root, &patch) {
    Err(err) if err.to_string().contains("patch removal mismatch") => {
        let fresh = regenerate_patch_against_current_file(&file_path, &edit)?;
        apply_patch(&root, &fresh)?; // retry with fresh context
    }
    other => other?,
}

Prevention

When it happens

Trigger: The line to delete was already changed or removed; preceding context or removal lines desynchronized the cursor; whitespace differs between the `-` line and the file.

Common situations: Same drift causes as context-not-found: concurrent edits, stale file snapshots, line-ending differences.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16). Data as JSON: /api/errors/f2025c25fbc3b294. Report an issue: GitHub.