{"record":{"id":"79b1a6e43bd6be52","repo":"Hmbown/CodeWhale","slug":"unsupported-patch-line-raw-line","errorCode":null,"errorMessage":"unsupported patch line: {raw_line}","messagePattern":"unsupported patch line: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/eval.rs","lineNumber":742,"sourceCode":"                    ));\n                };\n                cursor = found + 1;\n            }\n            \"-\" => {\n                if cursor >= file_lines.len() || file_lines[cursor] != content {\n                    return Err(anyhow!(\n                        \"patch removal mismatch in {}: expected '{}'\",\n                        file_path.display(),\n                        content\n                    ));\n                }\n                file_lines.remove(cursor);\n            }\n            \"+\" => {\n                file_lines.insert(cursor, content);\n                cursor += 1;\n            }\n            _ => return Err(anyhow!(\"unsupported patch line: {raw_line}\")),\n        }\n    }\n\n    let mut updated = file_lines.join(\"\\n\");\n    if had_trailing_newline {\n        updated.push('\\n');\n    }\n\n    fs::write(&file_path, updated)\n        .with_context(|| format!(\"failed to write patched file {}\", file_path.display()))\n}\n\nfn run_bash(root: &Path, command: &str) -> Result<String> {\n    crate::shell_dispatcher::global_dispatcher().run_foreground(command, root)\n}\n\nfn truncate_output(value: &str, max_chars: usize) -> String {\n    if value.chars().count() <= max_chars {","sourceCodeStart":724,"sourceCodeEnd":760,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/crates/tui/src/eval.rs#L724-L760","documentation":"Every patch body line must begin with ` `, `-`, `+`, or `@@`; `*** End Patch` terminates input (eval.rs:742). A line whose first character is anything else — including a truly empty line (blank context must be a single space) or a `\\ No newline at end of file` marker — is unsupported.","triggerScenarios":"Model or transport strips the leading space from context lines; blank lines emitted with no prefix; unified-diff artifacts like `\\ No newline at end of file` leak into the patch body.","commonSituations":"Whitespace-trimming editors or transports; dialect mixing from different diff formats.","solutions":["Ensure every body line keeps its prefix character; blank context lines are exactly one space","Strip `\\ No newline at end of file` and other non-format lines before applying","Validate line prefixes up front"],"exampleFix":"// before: context lines lost their leading space\n// after: re-prefix unsupported lines\nlet fixed: Vec<String> = patch.lines().map(|l| {\n    match l.chars().next() {\n        Some(' ') | Some('-') | Some('+') | Some('@') => l.to_string(),\n        _ => format!(\" {l}\"),\n    }\n}).collect();","handlingStrategy":"validation","validationCode":"fn patch_lines_supported(patch: &str) -> bool {\n    patch.lines()\n        .skip(2)\n        .take_while(|l| *l != \"*** End Patch\")\n        .all(|l| {\n            !l.starts_with(\"*** \")\n                && matches!(l.chars().next(), Some(' ') | Some('-') | Some('+') | Some('@'))\n        })\n}\nanyhow::ensure!(patch_lines_supported(&patch), \"patch contains unsupported lines\");","typeGuard":"fn patch_lines_supported(patch: &str) -> bool {\n    patch.lines()\n        .skip(2)\n        .take_while(|l| *l != \"*** End Patch\")\n        .all(|l| {\n            !l.starts_with(\"*** \")\n                && matches!(l.chars().next(), Some(' ') | Some('-') | Some('+') | Some('@'))\n        })\n}","tryCatchPattern":null,"preventionTips":["Preserve leading prefix characters end-to-end; disable whitespace trimming on the transport","Represent blank context lines as a single space, never an empty line","Strip `\\ No newline at end of file` artifacts before applying"],"tags":["patch","parsing","whitespace","eval"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}