databendlabs/databend · error
failed to build jsonb array
Error message
failed to build jsonb array
What it means
cast_scalar_to_variant converts an Array scalar into a jsonb value; it collects per-element variants and calls OwnedJsonb::build_array, expecting array construction to succeed. The panic fires when jsonb's build_array returns an error — typically because the accumulated document exceeds jsonb size limits (depth/size constraints of the jsonb format), or an internal jsonb encoding failure.
Solutions
- Reduce array size/nesting before casting to VARIANT.
- Replace expect with error propagation returning ErrorCode (e.g. jsonb build failure) to fail the query gracefully.
- Check jsonb crate limits and enforce an application-level limit on array length in cast functions.
Example fix
// before
let owned_jsonb = OwnedJsonb::build_array(items.iter().map(RawJsonb::new))
.expect("failed to build jsonb array");
// after
let owned_jsonb = OwnedJsonb::build_array(items.iter().map(RawJsonb::new))
.map_err(|e| ErrorCode::BadArguments(format!("failed to build jsonb array: {e}")))?; Defensive patterns
Strategy: fallback
Validate before calling
if items.len() > MAX_JSONB_ARRAY_ITEMS {
return Err(ErrorCode::BadArguments("array 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(scalar, tz, &mut buf, table_data_type);
}));
if result.is_err() { /* fail query gracefully or emit NULL variant */ } Prevention
- Cap array size/nesting before VARIANT casts in queries.
- Prefer explicit size-limit errors over reaching jsonb build limits.
When it happens
Trigger: Casting an ARRAY scalar with a very large number of elements or very large encoded items such that the built jsonb exceeds internal size limits; recursive cast_scalar_to_variant → cast_scalars_to_variants on deeply nested arrays.
Common situations: Queries constructing huge arrays via ARRAY(...) or array_agg then casting to VARIANT/JSON; deeply nested array literals blowing jsonb depth limits during expression evaluation.
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 object from map
- must array type
- failed to build jsonb object from tuple
- failed to parse geojson to json value
- {}
AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11).
Data as JSON: /api/errors/f55796e7e6d90638.
Report an issue: GitHub.
Appendix: source
Thrown at src/query/expression/src/types/variant.rs:308
}),
ScalarRef::Date(d) => jsonb::Value::Date(jsonb::Date { value: d }),
ScalarRef::Interval(i) => {
let interval = jsonb::Interval {
months: i.months(),
days: i.days(),
micros: i.microseconds(),
};
jsonb::Value::Interval(interval)
}
ScalarRef::Array(col) => {
let typ = if let Some(TableDataType::Array(typ)) = table_data_type {
Some(typ.remove_nullable())
} else {
None
};
let items = cast_scalars_to_variants(col.iter(), tz, typ.as_ref());
let owned_jsonb = OwnedJsonb::build_array(items.iter().map(RawJsonb::new))
.expect("failed to build jsonb array");
buf.extend_from_slice(owned_jsonb.as_ref());
return;
}
ScalarRef::Map(col) => {
let typ = if let Some(TableDataType::Map(typ)) = table_data_type {
Some(typ.remove_nullable())
} else {
None
};
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(),View on GitHub (pinned to 288d84d76e)