pola-rs/polars · error

Deserialization from JSON not implemented for {adt:?}

Error message

Deserialization from JSON not implemented for {adt:?}

What it means

Catch-all arm of the polars-json deserializer: schema-driven JSON parsing only supports booleans, numerics (incl. Int128/UInt128/Float16), decimals, timestamps, dates, times, durations, LargeUtf8/Utf8View strings, LargeBinary, LargeList, and Struct. Any other ArrowDataType - legacy Utf8, plain Binary, Map, FixedSizeList, Dictionary, Extension - panics as unimplemented.

Source

Thrown at crates/polars-json/src/json/deserialize.rs:535

        ArrowDataType::Decimal(_, _) => Ok(Box::new(deserialize_decimal(rows, dtype)?)),
        ArrowDataType::LargeUtf8 => {
            fill_generic_array_from::<_, _, Utf8Array<i64>>(deserialize_utf8_into, rows)
        },
        ArrowDataType::Utf8View => {
            fill_generic_array_from::<_, _, Utf8ViewArray>(deserialize_utf8view_into, rows)
        },
        ArrowDataType::LargeList(_) => Ok(Box::new(deserialize_list(
            rows,
            dtype,
            allow_extra_fields_in_struct,
        )?)),
        ArrowDataType::LargeBinary => Ok(Box::new(deserialize_binary(rows)?)),
        ArrowDataType::Struct(_) => Ok(Box::new(deserialize_struct(
            rows,
            dtype,
            allow_extra_fields_in_struct,
        )?)),
        adt => unimplemented!("Deserialization from JSON 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),
    }
}

View on GitHub (pinned to df599052da)

Solutions

  1. Replace unsupported dtypes in the schema: String for Utf8, String for Dictionary keys, List for FixedSizeList/Map (or Struct for maps)
  2. Let polars infer the schema first, then cast the offending column after reading
  3. Upgrade polars - JSON dtype coverage expands over releases

Example fix

# before
pl.read_ndjson("x.ndjson", schema={"blob": pl.Binary, "kv": pl.Map})  # panics

# after
pl.read_ndjson("x.ndjson", schema={"blob": pl.String, "kv": pl.Struct})
Defensive patterns

Strategy: validation

Validate before calling

JSON_SAFE = (
    set(pl.INTEGER_DTYPES) | set(pl.FLOAT_DTYPES)
    | {pl.Boolean, pl.String, pl.Utf8, pl.Binary, pl.Null}
    | {pl.Date, pl.Time, pl.Duration}
)
def json_schema_ok(schema: dict) -> bool:
    def ok(dt):
        if dt in JSON_SAFE or isinstance(dt, (pl.Datetime, pl.Struct, pl.List, pl.Decimal)):
            return not isinstance(dt, pl.List) or ok(dt.inner)
        if isinstance(dt, pl.Struct):
            return all(ok(f.dtype) for f in dt.fields)
        return False
    return all(ok(dt) for dt in schema.values())

Type guard

def unsupported_json_dtypes(schema: dict) -> list[str]:
    bad = []
    for name, dt in schema.items():
        if isinstance(dt, (pl.Map, pl.Array)) or dt in (pl.Utf8, pl.Binary):
            bad.append(name)
    return bad

Prevention

When it happens

Trigger: pl.read_json / pl.read_ndjson / scan_ndjson with a schema containing an unsupported dtype, e.g. schema={"k": pl.Binary} (non-large Binary), Map, FixedSizeList, or legacy Utf8 obtained from Arrow schema conversion.

Common situations: Schemas round-tripped from Arrow IPC/Parquet (which allow Dictionary, Map, FixedSizeList, Utf8) and applied directly to JSON readers; version drift where a previously-tolerated dtype now reaches this fallback.

Related errors


AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16). Data as JSON: /api/errors/6e61c1225f79a10e. Report an issue: GitHub.