{"record":{"id":"de91ce95aa6853cc","repo":"astral-sh/ruff","slug":"unexpected-annotation-type-annotation","errorCode":null,"errorMessage":"unexpected annotation type: {annotation:?}","messagePattern":"unexpected annotation type: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/ruff_annotate_snippets/src/renderer/render.rs","lineNumber":1428,"sourceCode":"                uline.underline,\n                uline.style,\n            );\n        }\n\n        if pos == 0\n            && matches!(\n                annotation.annotation_type,\n                LineAnnotationType::MultilineStart(_) | LineAnnotationType::MultilineEnd(_)\n            )\n        {\n            // The beginning of a multiline span with its leftward moving line on the same line.\n            buffer.putc(\n                line_offset + 1,\n                (code_offset + annotation.start.display).saturating_sub(left),\n                match annotation.annotation_type {\n                    LineAnnotationType::MultilineStart(_) => uline.top_right_flat,\n                    LineAnnotationType::MultilineEnd(_) => uline.multiline_end_same_line,\n                    _ => panic!(\"unexpected annotation type: {annotation:?}\"),\n                },\n                uline.style,\n            );\n        } else if pos != 0\n            && matches!(\n                annotation.annotation_type,\n                LineAnnotationType::MultilineStart(_) | LineAnnotationType::MultilineEnd(_)\n            )\n        {\n            // The beginning of a multiline span with its leftward moving line on another line,\n            // so we start going down first.\n            buffer.putc(\n                line_offset + 1,\n                (code_offset + annotation.start.display).saturating_sub(left),\n                match annotation.annotation_type {\n                    LineAnnotationType::MultilineStart(_) => uline.multiline_start_down,\n                    LineAnnotationType::MultilineEnd(_) => uline.multiline_end_up,\n                    _ => panic!(\"unexpected annotation type: {annotation:?}\"),","sourceCodeStart":1410,"sourceCodeEnd":1446,"githubUrl":"https://github.com/astral-sh/ruff/blob/d1087a4b9e03d253a88703f34e0869ee4b805456/crates/ruff_annotate_snippets/src/renderer/render.rs#L1410-L1446","documentation":"Defensive arm in the multiline-underline drawing code of the vendored renderer. The branch is entered only when matches! has already confirmed the annotation type is MultilineStart or MultilineEnd ('the beginning of a multiline span with its leftward moving line on the same line'), so the '_ => panic!' arm exists purely to satisfy exhaustiveness. Reaching it means the renderer's internal annotation classification became inconsistent — an internal bug in ruff_annotate_snippets rather than a misuse of the documented API.","triggerScenarios":"Rendering a diagnostic with multiline spans in a combination that trips a classification bug (e.g. multiline markers landing at column 0 or start/end markers sharing a line); the panic fires while drawing the underline row of the snippet.","commonSituations":"New snapshot tests with unusual multiline spans; changes to the vendored ruff_annotate_snippets fork; diagnostics built from hand-constructed ranges instead of real files.","solutions":["Minimize the failing case to source text plus span ranges in a ruff_annotate_snippets test and report it to the ruff repository — this arm is unreachable by design and needs a library fix.","Pin to the last known-good ruff_annotate_snippets revision until the fix lands.","As a local workaround, adjust the offending annotation (e.g. clamp the multiline span to a single line) so the multiline drawing path is not taken."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"fn spans_sane(source: &str, anns: &[Annotation<'_>]) -> bool {\n    let len = source.len();\n    anns.iter().all(|a| a.span.start <= a.span.end && a.span.end <= len + 1)\n}","typeGuard":null,"tryCatchPattern":"let out = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {\n    renderer.render(&report)\n}))\n.unwrap_or_else(|_| format!(\"{path}: {title}\")); // degrade to a location-only line","preventionTips":["Pin and snapshot-test the vendored ruff_annotate_snippets revision.","Derive annotation spans from one current source; avoid hand-built multiline ranges.","When a multiline render panics, minimize to source + ranges and report upstream rather than papering over it."],"tags":["diagnostics","rendering","panic","multiline-annotation","annotate-snippets"],"backgroundTag":"unreachable-match-arm-panic","analyzedSha":"d1087a4b9e03d253a88703f34e0869ee4b805456","analyzedAt":"2026-08-20T16:33:49.445Z","contentChangedAt":"2026-08-20T16:33:49.445Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}