{"record":{"id":"bf3c91d6eb4e2b81","repo":"rtk-ai/rtk","slug":"a-bodyless-region-of-prose-must-not-force-raw","errorCode":null,"errorMessage":"a bodyless region of prose must not force raw","messagePattern":"a bodyless region of prose must not force raw","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/cmds/git/diff_cmd.rs","lineNumber":6972,"sourceCode":"        // Closing at end of stream, not at a separator, judges it the same.\n        let last = \"From bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb Mon Sep 17 00:00:00 2001\\nSubject: [PATCH 1/2] one\\n\\ndiff --git a/y.txt b/y.txt\\n--- a/y.txt\\n+++ b/y.txt\\n@@ -1 +1 @@\\n-p\\n+q\\n-- \\n2.54.0\\n\\nFrom aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Mon Sep 17 00:00:00 2001\\nSubject: [PATCH 2/2] two\\n\\n-a\\n+b\\n-- \\n2.54.0\\n\";\n        assert!(\n            condense_unified_diff_strict(last).is_none(),\n            \"an orphaned body at end of stream must fall back raw\"\n        );\n\n        // Bodyless by construction - a cover letter or an `--always` empty\n        // commit - writes bullets, and bullets keep their shape.\n        for prose in [\n            \"- first, it changes a to b\\n- second, it changes b to c\",\n            \"Before and after:\\n- old_value = 1\\n+ new_value = 2\",\n            \"A rule:\\n---------\\nand a bullet:\\n- done\",\n            // Prose that wrapped a long option to column 0, which is how\n            // 11.7% of this repo's marked-line messages break bullet shape.\n            \"The relevant invocation is\\n--no-stat --cover-letter\\nwhich changes nothing here.\",\n        ] {\n            let out = condense_unified_diff_strict(&series.replace(\"BODY\", prose))\n                .expect(\"a bodyless region of prose must not force raw\");\n            assert!(out.contains(\"[file] y.txt (+1 -1)\"), \"got:\\n{out}\");\n        }\n    }\n\n    #[test]\n    fn u0_and_omitted_counts_parse() {\n        // `-U0` produces `@@ -3 +3 @@` (omitted count = 1) and zero-count\n        // ranges like `@@ -5,0 +6 @@`.\n        let fixture = include_str!(\"../../../tests/fixtures/diff/git_diff_u0_raw.txt\");\n        let out = condense_unified_diff(fixture);\n        assert_ne!(out, fixture, \"-U0 fell back to raw\");\n        assert!(out.contains(\"[file] main.rs (+2 -1)\"), \"got:\\n{out}\");\n    }\n\n    // --- region parser: the safety net must fire on structural disagreement ---\n\n    #[test]\n    fn truncated_hunk_falls_back_to_raw() {","sourceCodeStart":6954,"sourceCodeEnd":6990,"githubUrl":"https://github.com/rtk-ai/rtk/blob/0924356b4caba4989607227b7c8824d3d8098719/src/cmds/git/diff_cmd.rs#L6954-L6990","documentation":"Test panic from `.expect(\"a bodyless region of prose must not force raw\")`: `condense_unified_diff_strict` returned `Err` for patch bodies whose prose contains column-0 lines that superficially look like marked lines — an ASCII rule (`---------`), a bullet (`- done`), or a wrapped command line reaching column 0 (`--no-stat --cover-letter`). The parser must not classify such bodyless prose as lost marked-line content, which would force raw output and fail the parse assertion.","triggerScenarios":"Substituting each prose sample (rule line, bullet, long-option wrapped to column 0) into the BODY slot of a patch series template and calling `condense_unified_diff_strict`; the marked-line detector must tolerate these shapes and still emit `[file] y.txt (+1 -1)`.","commonSituations":"Commit messages wrapping long CLI options to column 0 (reported as ~11.7% of marked-line messages in this repo), ASCII underlines, and markdown bullets all mimic the marked-line shape.","solutions":["Replace the expect with a match that includes the substituted prose in the panic message to identify which sample broke.","Tighten the marked-line heuristic: only treat `- ` bullets past the diffstat as marked lines, not raw column-0 dashes or option-like lines inside the message body.","Keep each prose shape as a regression fixture in the test list."],"exampleFix":"// before\n.expect(\"a bodyless region of prose must not force raw\");\n// after\n.unwrap_or_else(|e| panic!(\"prose must not force raw: {e}\\nprose sample:\\n{prose}\"));","handlingStrategy":"validation","validationCode":"// heuristic pre-check: rule lines and option-like column-0 text are prose\nlet looks_like_marked = |l: &str| l.starts_with(\"- \") && !l.starts_with(\"---\");","typeGuard":null,"tryCatchPattern":"let out = condense_unified_diff_strict(&series.replace(\"BODY\", prose))\n    .unwrap_or_else(|e| panic!(\"prose must not force raw: {e}\\nprose:\\n{prose}\"));","preventionTips":["Enumerate prose shapes that mimic marked lines (rules, bullets, wrapped options) as fixtures","Restrict marked-line detection to lines after the diffstat","Track repo-wide frequency of wrapped-option messages when tuning heuristics"],"tags":["rust","test-assertion","prose-parsing"],"backgroundTag":"internal-invariant-violation","analyzedSha":"0924356b4caba4989607227b7c8824d3d8098719","analyzedAt":"2026-09-19T19:25:29.612Z","contentChangedAt":"2026-09-19T19:25:29.612Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}