{"record":{"id":"7acd9f5eff5726f9","repo":"databendlabs/databend","slug":"linestring-geometry-7acd9f","errorCode":null,"errorMessage":"linestring geometry","messagePattern":"linestring geometry","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/query/expression/src/geographic/overlay.rs","lineNumber":159,"sourceCode":"        if elements.is_empty() {\n            return None;\n        }\n\n        if elements.iter().all(|geo| matches!(geo, Geometry::Point(_))) {\n            let points: Vec<Point<f64>> = elements\n                .into_iter()\n                .map(|geo| geo.try_into().expect(\"point geometry\"))\n                .collect();\n            return Some(Geometry::MultiPoint(MultiPoint::from_iter(points)));\n        }\n\n        if elements\n            .iter()\n            .all(|geo| matches!(geo, Geometry::LineString(_)))\n        {\n            let lines: Vec<LineString<f64>> = elements\n                .into_iter()\n                .map(|geo| geo.try_into().expect(\"linestring geometry\"))\n                .collect();\n            return Some(Geometry::MultiLineString(MultiLineString::from_iter(lines)));\n        }\n\n        if elements\n            .iter()\n            .all(|geo| matches!(geo, Geometry::Polygon(_)))\n        {\n            let polygons: Vec<Polygon<f64>> = elements\n                .into_iter()\n                .map(|geo| geo.try_into().expect(\"polygon geometry\"))\n                .collect();\n            return Some(Geometry::MultiPolygon(MultiPolygon::from_iter(polygons)));\n        }\n\n        Some(Geometry::GeometryCollection(GeometryCollection::from_iter(\n            elements,\n        )))","sourceCodeStart":141,"sourceCodeEnd":177,"githubUrl":"https://github.com/databendlabs/databend/blob/288d84d76e20a2f8f7173bda9691eb6ece301aa9/src/query/expression/src/geographic/overlay.rs#L141-L177","documentation":"In geographic overlay's `build_geometry_from_elements`, when all elements are `Geometry::LineString(_)`, each is converted with `try_into().expect(\"linestring geometry\")` to build a MultiLineString. The preceding guard should make the conversion infallible; the panic indicates the LineString TryFrom impl rejected a guarded value — an invariant violation or malformed linestring from the overlay step.","triggerScenarios":"Overlay results composed entirely of linestrings where the `TryFrom<Geometry> for LineString<f64>` conversion fails — e.g. overlay-produced linestrings with too few points or invalid coordinate sequences.","commonSituations":"Overlaying adjacent polygons producing sliver linestrings; geo crate upgrades; precision artifacts generating degenerate lines.","solutions":["Check overlay output linestrings for degenerate coordinate lists.","Confirm geo crate version compatibility of the conversion impl.","Replace expect with `.ok()`/`None` propagation consistent with the function's Option contract."],"exampleFix":"// before\n.map(|geo| geo.try_into().expect(\"linestring geometry\"))\n// after\n.map(|geo| geo.try_into().ok())\n.collect::<Option<Vec<_>>>()?;","handlingStrategy":"validation","validationCode":"// before overlay:\nlet valid = geoms.iter().all(|g| matches!(g, Geometry::LineString(l) if l.coords().count() >= 2));","typeGuard":"fn is_valid_linestring(g: &Geometry) -> bool { matches!(g, Geometry::LineString(l) if l.coords().count() >= 2) }","tryCatchPattern":"let result = std::panic::catch_unwind(|| overlay(geoms.clone()));","preventionTips":["Validate linestring minimum coordinate count before overlay.","Watch for precision artifacts when overlaying sliver geometries.","Test overlay operations after any geo crate upgrade."],"tags":["rust","geospatial","overlay"],"backgroundTag":"internal-invariant-violation","analyzedSha":"288d84d76e20a2f8f7173bda9691eb6ece301aa9","analyzedAt":"2026-09-11T11:29:36.208Z","contentChangedAt":"2026-09-11T11:29:36.208Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}