{"record":{"id":"73ba84b729ab6354","repo":"Hmbown/CodeWhale","slug":"code-rows-are-never-empty","errorCode":null,"errorMessage":"code rows are never empty","messagePattern":"code rows are never empty","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/tui/markdown_render.rs","lineNumber":1280,"sourceCode":"\nfn render_wrapped_code_spans_tagged(\n    spans: Vec<Span<'static>>,\n    width: usize,\n) -> Vec<RenderedMarkdownLine> {\n    let prefix = \"  \";\n    let prefix_width = prefix.width();\n    let available = width.saturating_sub(prefix_width).max(1);\n    let mut rows: Vec<Vec<(String, Style)>> = vec![Vec::new()];\n    let mut current_width = 0usize;\n\n    for span in spans {\n        for grapheme in span.content.graphemes(true) {\n            let grapheme_width = markdown_grapheme_width(grapheme, current_width);\n            if current_width + grapheme_width > available && current_width > 0 {\n                rows.push(Vec::new());\n                current_width = 0;\n            }\n            let row = rows.last_mut().expect(\"code rows are never empty\");\n            if let Some((text, style)) = row.last_mut()\n                && *style == span.style\n            {\n                text.push_str(grapheme);\n            } else {\n                row.push((grapheme.to_string(), span.style));\n            }\n            current_width += markdown_grapheme_width(grapheme, current_width);\n        }\n    }\n\n    let last_index = rows.len().saturating_sub(1);\n    rows.into_iter()\n        .enumerate()\n        .map(|(idx, row)| {\n            let mut rendered = vec![Span::raw(prefix)];\n            rendered.extend(\n                row.into_iter()","sourceCodeStart":1262,"sourceCodeEnd":1298,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/tui/markdown_render.rs#L1262-L1298","documentation":"render_wrapped_code_spans_tagged seeds rows with one empty Vec and only pushes additional rows, never popping, so at least one row always exists when it finishes wrapping code-span graphemes. The expect fires only if row-initialization logic regressed and all rows were drained — an internal rendering invariant, independent of input span content.","triggerScenarios":"Thrown at crates/tui/src/tui/markdown_render.rs:1280 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Keep the vec![Vec::new()] seed; append rows instead of replacing the vector","If empty input should yield zero rows, change the function to return Option rather than expecting","Add a test for empty spans producing exactly one (empty) row"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}