databendlabs/databend · error
failed to build jsonb object from map
Error message
failed to build jsonb object from map
What it means
cast_scalar_to_variant converts a Map scalar into a jsonb object by collecting key/value pairs and calling OwnedJsonb::build_object, expecting object construction to succeed. The panic fires when jsonb's build_object errors — typically when the resulting object exceeds jsonb format size limits or encoding fails internally.
Solutions
- Reduce map size before casting to VARIANT.
- Replace expect with error propagation returning a proper ErrorCode for map-to-jsonb build failures.
- Enforce a key/value size limit on maps destined for VARIANT conversion.
Example fix
// before
let owned_jsonb = OwnedJsonb::build_object(kvs.iter().map(|(k, v)| (k, RawJsonb::new(&v[..]))))
.expect("failed to build jsonb object from map");
// after
let owned_jsonb = OwnedJsonb::build_object(kvs.iter().map(|(k, v)| (k, RawJsonb::new(&v[..]))))
.map_err(|e| ErrorCode::BadArguments(format!("failed to build jsonb object: {e}")))?; Defensive patterns
Strategy: fallback
Validate before calling
if serialized_size(kvs) > MAX_JSONB_OBJECT_SIZE {
return Err(ErrorCode::BadArguments("map too large to cast to VARIANT"));
} Try / catch
// Catch panics around cast if it cannot be changed:
let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
cast_scalar_to_variant(v, tz, &mut buf, typ.as_ref());
}));
if result.is_err() { /* fail query gracefully or emit NULL variant */ } Prevention
- Cap map size before VARIANT casts in queries.
- Return a build failure ErrorCode instead of expect when jsonb build_object errors.
When it happens
Trigger: Casting a MAP scalar whose serialized size (keys plus values) exceeds jsonb build limits, or containing items that fail jsonb encoding; maps built from very large or deeply nested values.
Common situations: Casting large MAP(...) results or map_agg outputs to VARIANT/JSON in queries; wide maps from aggregation hitting the jsonb document size cap.
Understand the failure class
Background: "JSON serialization failed", "not JSON serializable", "Failed to serialize": why JSON marshaling errors happen and how to fix them — this error's family across 46 libraries.
Related errors
- failed to build jsonb array
- failed to build jsonb object from tuple
- failed to parse geojson to json value
- {}
- Temp table id used up
AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11).
Data as JSON: /api/errors/45d8ac152ceb397a.
Report an issue: GitHub.
Appendix: source
Thrown at src/query/expression/src/types/variant.rs:337
let kv_col = KvPair::<AnyType, AnyType>::try_downcast_column(&col).unwrap();
let mut kvs = BTreeMap::new();
for (k, v) in kv_col.iter() {
let key = match k {
ScalarRef::String(v) => v.to_string(),
ScalarRef::Number(v) => v.to_string(),
ScalarRef::Decimal(v) => v.to_string(),
ScalarRef::Boolean(v) => v.to_string(),
ScalarRef::Timestamp(v) => timestamp_to_string(v, tz).to_string(),
ScalarRef::Date(v) => date_to_string(v).to_string(),
_ => unreachable!(),
};
let mut val = vec![];
cast_scalar_to_variant(v, tz, &mut val, typ.as_ref());
kvs.insert(key, val);
}
let owned_jsonb =
OwnedJsonb::build_object(kvs.iter().map(|(k, v)| (k, RawJsonb::new(&v[..]))))
.expect("failed to build jsonb object from map");
buf.extend_from_slice(owned_jsonb.as_ref());
return;
}
ScalarRef::Bitmap(b) => {
jsonb::Value::Array(
deserialize_bitmap(b)
.unwrap()
.iter()
.map(|x| x.into())
.collect(),
)
.write_to_vec(buf);
return;
}
ScalarRef::Tuple(fields) => {
let owned_jsonb = match table_data_type {
Some(TableDataType::Tuple {
fields_name,View on GitHub (pinned to 288d84d76e)