{"record":{"id":"00458f5c69455b0a","repo":"gitbutlerapp/gitbutler","slug":"withsyntaxhighlighting-ensures-the-line-is-highlig","errorCode":null,"errorMessage":"WithSyntaxHighlighting ensures the line is highlighted","messagePattern":"WithSyntaxHighlighting ensures the line is highlighted","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but/src/command/legacy/diff2.rs","lineNumber":360,"sourceCode":"impl DiffLineWriter for DiffWriter<'_> {\n    fn write(&mut self, line: DetailsLine) -> anyhow::Result<()> {\n        match line {\n            DetailsLine::Text { line, .. } => {\n                let line_style = line.style;\n                for span in line.spans {\n                    let rendered = line_style.patch(span.style).paint(&span.content);\n                    write!(self.out, \"{rendered}\")?;\n                }\n                writeln!(self.out)?;\n            }\n            DetailsLine::TextToWrap { id: _, text } => {\n                writeln!(self.out, \"{text}\")?;\n            }\n            DetailsLine::Code(code_line) => {\n                let syntax_highlighted_line = code_line.syntax_highlighted_line.borrow();\n                let syntax_highlighted_line = syntax_highlighted_line\n                    .as_ref()\n                    .expect(\"WithSyntaxHighlighting ensures the line is highlighted\");\n\n                let line_style = syntax_highlighted_line.style;\n                for span in syntax_highlighted_line {\n                    let rendered = line_style.patch(span.style).paint(&span.content);\n                    write!(self.out, \"{rendered}\")?;\n                }\n                if line_style.bg.is_some() && colored::control::SHOULD_COLORIZE.should_colorize() {\n                    write!(self.out, \"{}\", line_style.paint(CLEAR_TO_END_OF_LINE))?;\n                }\n                writeln!(self.out)?;\n            }\n            DetailsLine::SectionSeparator => {\n                writeln!(self.out)?;\n            }\n            DetailsLine::HunkHeader { width, line, .. } => {\n                for _ in 0..width {\n                    write!(self.out, \"{}\", self.theme.border.paint(\"─\"))?;\n                }","sourceCodeStart":342,"sourceCodeEnd":378,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/2497b8007aa4a1922dae9a805b32ffe5b5037785/crates/but/src/command/legacy/diff2.rs#L342-L378","documentation":"Rendering invariant panic in the diff-details printer: a DetailsLine::Code line is being printed, but its syntax_highlighted_line RefCell is still None. Code lines get their highlighted spans pre-computed only when the details sink runs wrapped in WithSyntaxHighlighting, which fills the cache during iteration; printing Code lines through a path that skipped that wrapper trips the expect.","triggerScenarios":"A code path constructs the details renderer without the WithSyntaxHighlighting wrapper yet still emits DetailsLine::Code; a refactor moves highlighting from construction time to render time for some formats only; a feature-gated highlighter is compiled out while Code lines still render.","commonSituations":"Refactors of the diff rendering pipeline; machine-readable formats accidentally routed through the human renderer; new details line kinds added without extending the highlighting pass.","solutions":["Wrap the printing sink in WithSyntaxHighlighting on the offending path before lines are produced","If highlighting is intentionally unavailable there, render the plain line text instead of expecting cached spans","File an issue with the exact 'but diff ...' invocation - the invariant must hold for all public flag combinations"],"exampleFix":"// before\nlet syntax_highlighted_line = syntax_highlighted_line.as_ref()\n    .expect(\"WithSyntaxHighlighting ensures the line is highlighted\");\n\n// after - degrade to plain text instead of panicking\nlet Some(hl) = code_line.syntax_highlighted_line.borrow().as_ref() else {\n    writeln!(self.out, \"{}\", code_line.content)?; // field per DetailsLine::Code\n    continue;\n};","handlingStrategy":"validation","validationCode":"// Renderer-side invariant test: every Code line must be pre-highlighted before print\nfn assert_all_code_lines_highlighted(lines: &[DetailsLine]) {\n    for line in lines {\n        if let DetailsLine::Code(c) = line {\n            assert!(c.syntax_highlighted_line.borrow().is_some(), \"Code line never highlighted\");\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Wrap every details-printing sink in WithSyntaxHighlighting at construction time, not selectively","When adding output formats, route them through the same highlighter setup as human output","Degrade to plain text (let-else + continue) instead of expecting cached highlights"],"tags":["rust","panic","diff","syntax-highlighting","rendering","invariant"],"backgroundTag":"internal-invariant-panic","analyzedSha":"2497b8007aa4a1922dae9a805b32ffe5b5037785","analyzedAt":"2026-08-17T00:30:25.648Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}