{"record":{"id":"b7d0e9e10bf50df9","repo":"databendlabs/databend","slug":"failed-to-decode-wkb-data","errorCode":null,"errorMessage":"failed to decode wkb data","messagePattern":"failed to decode wkb data","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/query/expression/src/types/variant.rs","lineNumber":398,"sourceCode":"                    let values = cast_scalars_to_variants(fields, tz, None);\n                    OwnedJsonb::build_object(\n                        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,","sourceCodeStart":380,"sourceCodeEnd":416,"githubUrl":"https://github.com/databendlabs/databend/blob/288d84d76e20a2f8f7173bda9691eb6ece301aa9/src/query/expression/src/types/variant.rs#L380-L416","documentation":"`cast_scalar_to_variant` converts a Geometry scalar to VARIANT by decoding EWKB with `Ewkb::to_json()`; the `expect(\"failed to decode wkb data\")` panics when the WKB/EWKB payload cannot be decoded. The code assumes any value stored in a Geometry column is valid EWKB.","triggerScenarios":"Calling `cast_scalar_to_variant` on a `ScalarRef::Geometry(bytes)` whose bytes are not valid EWKB (truncated header, bad geometry type code, corrupted SRID/coords), or a GEOGRAPHY value hitting the same `Ewkb(bytes.0).to_json().expect(...)` in the next branch.","commonSituations":"External tools wrote non-EWKB bytes into a geometry column; data imported from another system (e.g. raw WKT or MySQL binary geometry) without conversion; byte corruption in storage or during copy; version mismatch in geometry encoding.","solutions":["Validate the offending bytes with a WKB parser (e.g. postgis `ST_GeomFromWKB`, or wkb crate) to pinpoint the malformation.","Re-ingest the geometry from source, converting properly (e.g. ST_AsBinary / EWKB encoding) before loading into the Geometry column.","Check for ingestion paths that bypass geometry validation and add validation at load time.","Patch locally: replace `expect` with error propagation so bad rows surface as query errors naming the corrupt value instead of a panic."],"exampleFix":"// before\nlet geom = Ewkb(bytes).to_json().expect(\"failed to decode wkb data\");\n// after\nlet geom = Ewkb(bytes).to_json().map_err(|e| ErrorCode::Internal(format!(\"failed to decode wkb data: {e}\")))?;","handlingStrategy":"validation","validationCode":"// validate EWKB before casting: header magic byte + minimal length\nfn looks_like_ewkb(b: &[u8]) -> bool {\n    b.len() >= 5 && (b[0] == 0x00 || b[0] == 0x01)\n}\n// pre-check: looks_like_ewkb(geom_bytes)","typeGuard":"fn is_valid_ewkb(bytes: &[u8]) -> bool { bytes.len() >= 5 && matches!(bytes[0], 0x00 | 0x01) }","tryCatchPattern":null,"preventionTips":["Always ingest geometry as EWKB (e.g. ST_AsBinary output)","Add load-time geometry validation on ingest paths","Never write WKT or foreign binary geometry directly into Geometry columns"],"tags":["rust","geometry","ewkb","panic","data-corruption"],"backgroundTag":"invalid-argument-format","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"}