pola-rs/polars · error
read an Array from a non-Array data type
Error message
read an Array from a non-Array data type
What it means
The public json::deserialize(json, dtype, ...) requires that when the top-level JSON value is an Array, the target dtype is LargeList - it dispatches to _deserialize on the inner elements. Any other dtype with an array root hits todo!(). It is a caller-contract violation: array-shaped JSON must target a list type; scalar dtypes must be fed element-wise (which is what internal callers do).
Source
Thrown at crates/polars-json/src/json/deserialize.rs:551
allow_extra_fields_in_struct,
)?)),
adt => polars_bail!(
ComputeError: "deserialization from JSON is not implemented for `{adt:?}`"
),
}
}
pub fn deserialize(
json: &BorrowedValue,
dtype: ArrowDataType,
allow_extra_fields_in_struct: bool,
) -> PolarsResult<Box<dyn Array>> {
match json {
BorrowedValue::Array(rows) => match dtype {
ArrowDataType::LargeList(inner) => {
_deserialize(rows, inner.dtype, allow_extra_fields_in_struct)
},
_ => todo!("read an Array from a non-Array data type"),
},
_ => _deserialize(&[json], dtype, allow_extra_fields_in_struct),
}
}
fn check_err_idx<'a>(
rows: &[impl Borrow<BorrowedValue<'a>>],
err_idx: usize,
type_name: &'static str,
) -> PolarsResult<()> {
if err_idx != rows.len() {
polars_bail!(
ComputeError:
r#"error deserializing value "{:?}" as {}.
Try increasing `infer_schema_length` or specifying a schema."#,
rows[err_idx].borrow(), type_name,
)View on GitHub (pinned to 68506541d2)
Solutions
- Wrap the target dtype: pass ArrowDataType::LargeList(inner) when the root is an array
- Or flatten first: iterate the array and call deserialize per element with the scalar dtype
- Check the root variant (BorrowedValue::Array vs other) before choosing the dtype
Example fix
// before
deserialize(&json_array, ArrowDataType::Int64, true) // todo!()
// after
deserialize(&json_array, ArrowDataType::LargeList(Box::new(Field::new("item", ArrowDataType::Int64, true))), true)
// or: for v in array_elements { deserialize(&v, ArrowDataType::Int64, true)?; } Defensive patterns
Strategy: type-guard
Validate before calling
use polars_json::json::BorrowedValue;
fn root_matches_dtype(v: &BorrowedValue, dtype: &ArrowDataType) -> bool {
match (v, dtype) {
(BorrowedValue::Array(_), ArrowDataType::LargeList(_)) => true,
(BorrowedValue::Array(_), _) => false,
(_, ArrowDataType::LargeList(_)) => false,
_ => true,
}
} Type guard
fn target_dtype_for_root(v: &BorrowedValue, elem: ArrowDataType) -> ArrowDataType {
match v {
BorrowedValue::Array(_) => ArrowDataType::LargeList(Box::new(
ArrowField::new("item", elem, true).into(),
)),
_ => elem,
}
} Prevention
- Never pass unshaped serde/simd-json bodies straight to deserialize - branch on the root variant first
- Wrap one-line shape checks in the interop layer where JSON meets Arrow dtypes
- Add tests covering array roots, scalar roots and mismatched dtypes
When it happens
Trigger: Calling polars_json::json::deserialize(&borrowed_value, ArrowDataType::Int64, ...) where borrowed_value is a JSON array like [1,2,3]; custom integrations that pass serde/simd-json parsed bodies straight through without checking the root shape.
Common situations: Hand-rolled interop feeding arbitrary JSON bodies to deserialize; assuming lenient coercion (array -> first element, single-element array -> scalar).
Related errors
- Deserialization from JSON not implemented for {adt:?}
- There is no natural representation of DayTime in JSON.
- unexpected dtype when deserializing ndjson
- Invalid time unit '{tu:?}' for Datetime.
- Invalid time unit '{tu:?}' for Duration.
AI-assisted analysis of pola-rs/polars@68506541d2 (2026-08-19).
Data as JSON: /api/errors/4f0fd4f446fe47b8.
Report an issue: GitHub.