{"record":{"id":"7a7090d188c5ff83","repo":"databendlabs/databend","slug":"failed-to-parse-geojson-to-json-value","errorCode":null,"errorMessage":"failed to parse geojson to json value","messagePattern":"failed to parse geojson to json value","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/query/expression/src/types/variant.rs","lineNumber":400,"sourceCode":"                        values\n                            .iter()\n                            .enumerate()\n                            .map(|(i, bytes)| (format!(\"{}\", i + 1), RawJsonb::new(bytes))),\n                    )\n                    .expect(\"failed to build jsonb object from tuple\")\n                }\n            };\n            buf.extend_from_slice(owned_jsonb.as_ref());\n            return;\n        }\n        ScalarRef::Variant(bytes) => {\n            buf.extend_from_slice(bytes);\n            return;\n        }\n        ScalarRef::Geometry(bytes) => {\n            let geom = Ewkb(bytes).to_json().expect(\"failed to decode wkb data\");\n            jsonb::parse_owned_jsonb_with_buf(geom.as_bytes(), buf)\n                .expect(\"failed to parse geojson to json value\");\n            return;\n        }\n        ScalarRef::Geography(bytes) => {\n            // todo: Implement direct conversion, omitting intermediate processes\n            let geom = Ewkb(bytes.0).to_json().expect(\"failed to decode wkb data\");\n            jsonb::parse_owned_jsonb_with_buf(geom.as_bytes(), buf)\n                .expect(\"failed to parse geojson to json value\");\n            return;\n        }\n        ScalarRef::Vector(scalar) => with_vector_number_type!(|NUM_TYPE| match scalar {\n            VectorScalarRef::NUM_TYPE(vals) => {\n                let items = cast_scalars_to_variants(\n                    vals.iter()\n                        .map(|n| ScalarRef::Number(NumberScalar::NUM_TYPE(*n))),\n                    tz,\n                    None,\n                );\n                let owned_jsonb = OwnedJsonb::build_array(items.iter().map(RawJsonb::new))","sourceCodeStart":382,"sourceCodeEnd":418,"githubUrl":"https://github.com/databendlabs/databend/blob/288d84d76e20a2f8f7173bda9691eb6ece301aa9/src/query/expression/src/types/variant.rs#L382-L418","documentation":"After decoding EWKB to a GeoJSON string, `cast_scalar_to_variant` re-parses that string with `jsonb::parse_owned_jsonb_with_buf` and panics with `expect(\"failed to parse geojson to json value\")` if parsing fails. This assumes `Ewkb::to_json()` always emits valid JSON.","triggerScenarios":"Casting a Geometry (or Geography, same pattern in the next branch) scalar to Variant where the EWKB decodes but the produced GeoJSON string cannot be parsed as JSONB — e.g. NaN/Infinity coordinates serialized invalidly, or a jsonb version whose parser rejects the emitted shape.","commonSituations":"Geometries with NaN/inf coordinates produced by upstream computation; mismatched jsonb crate versions between workspace members; exotic geometry types whose GeoJSON serialization regressed in the wkb/geo crates.","solutions":["Inspect the geometry for NaN/Infinity or out-of-range coordinates and clean/round-trip the data at ingest.","Align the jsonb and wkb crate versions in the workspace (cargo update consistently) and rebuild.","Reproduce with the failing geometry value and report upstream (wkb/jsonb crates) with the GeoJSON string that fails to parse.","Patch the expect into a mapped ErrorCode to avoid a process panic on bad geo data."],"exampleFix":"// before\njsonb::parse_owned_jsonb_with_buf(geom.as_bytes(), buf).expect(\"failed to parse geojson to json value\");\n// after\njsonb::parse_owned_jsonb_with_buf(geom.as_bytes(), buf)\n    .map_err(|e| ErrorCode::Internal(format!(\"failed to parse geojson to json value: {e}\")))?;","handlingStrategy":"validation","validationCode":"// reject geometries with non-finite coordinates before casting\nfn coords_finite(bytes: &[u8]) -> bool {\n    bytes.chunks_exact(8).all(|c| {\n        let v = f64::from_le_bytes(c.try_into().unwrap());\n        v.is_finite()\n    })\n}","typeGuard":"fn geojson_parseable(geom_json: &str) -> bool { serde_json::from_str::<serde_json::Value>(geom_json).is_ok() }","tryCatchPattern":null,"preventionTips":["Clean NaN/Infinity coordinates at data-ingest time","Keep jsonb/wkb crate versions consistent in the workspace","Round-trip test exotic geometry types after dependency upgrades"],"tags":["rust","jsonb","geojson","panic"],"backgroundTag":"json-parse-error","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"}