pola-rs/polars · error · TypeError
mapping item must be a datatype or datatype expression; foun
Error message
mapping item must be a datatype or datatype expression; found {qualified_type_name(dtype_expr)!r} What it means
pl.struct_with_fields (unstable) builds a Struct DataTypeExpr from a mapping of field name to dtype. Each value is preprocessed in Python and must be a DataType instance (pl.Int64()), a DataTypeClass (pl.Int64), or a DataTypeExpr; unlike many Polars APIs, string aliases like 'Int64' are not parsed here and raise this TypeError, as do numpy dtypes, None, and arbitrary objects.
Source
Thrown at py-polars/src/polars/functions/datatype.py:115
"""
Create a new datatype expression that represents a Struct datatype.
.. warning::
This functionality is considered **unstable**. It may be changed
at any point without it being considered a breaking change.
"""
from polars._plr import PyDataTypeExpr
def preprocess(dtype_expr: PolarsDataType | pl.DataTypeExpr) -> PyDataTypeExpr:
if isinstance(dtype_expr, pl.DataType):
return dtype_expr.to_dtype_expr()._pydatatype_expr
if isinstance(dtype_expr, pl.DataTypeClass):
return dtype_expr.to_dtype_expr()._pydatatype_expr
elif isinstance(dtype_expr, pl.DataTypeExpr):
return dtype_expr._pydatatype_expr
else:
msg = f"mapping item must be a datatype or datatype expression; found {qualified_type_name(dtype_expr)!r}"
raise TypeError(msg)
fields = [(name, preprocess(dtype_expr)) for (name, dtype_expr) in mapping.items()]
return pl.DataTypeExpr._from_pydatatype_expr(
PyDataTypeExpr.struct_with_fields(fields)
)
View on GitHub (pinned to df599052da)
Solutions
- Pass real dtypes: pl.struct_with_fields({'a': pl.Int64, 'b': pl.String})
- Convert string schemas first with polars.datatypes.parse_into_dtype in a dict comprehension
- For lazy per-column dtypes, combine dtype_of()/self_dtype() results, which are already DataTypeExprs
- Wrap the call defensively while the API is unstable and re-validate inputs on upgrade
Example fix
# before
pl.struct_with_fields({'a': 'Int64', 'b': 'String'})
# after
pl.struct_with_fields({'a': pl.Int64, 'b': pl.String})
# converting a string schema:
from polars.datatypes import parse_into_dtype
pl.struct_with_fields({k: parse_into_dtype(v) for k, v in raw_schema.items()}) Defensive patterns
Strategy: type-guard
Validate before calling
import polars as pl
from polars.datatypes import parse_into_dtype
clean = {
k: (v if isinstance(v, (pl.DataType, pl.DataTypeExpr)) else parse_into_dtype(v))
for k, v in raw_mapping.items()
}
expr = pl.struct_with_fields(clean) Type guard
def is_struct_field_dtype(x: object) -> bool:
return isinstance(x, (pl.DataType, pl.DataTypeExpr)) or (
isinstance(x, type) and hasattr(x, '__pl.TimeUnit__')
) Prevention
- Parse string dtype schemas once at load time, not per call
- Convert numpy/pandas dtypes to Polars dtypes at the boundary
- Pin and re-test the unstable API on every Polars upgrade
When it happens
Trigger: pl.struct_with_fields({'a': 'Int64'}) or {'a': 'int'}; schemas deserialized from JSON/YAML config; numpy/pandas dtype objects; None values from optional fields.
Common situations: Reusing a string-based schema dict that worked with pl.Schema or pl.DataFrame(schema=...); config-driven return dtypes for map_batches; mixing Python type objects (int) with Polars dtypes — plain classes are not accepted here either.
Related errors
- cannot treat NumPy array of type {arr.dtype} as indices
- "extract_groups" expects a `str`, given a {qualified_type_na
- expected type 'int | str', got {qualified_type_name(item)!r}
- `schema_overrides` should be of type list or dict, got {qual
- invalid dtype: {t!r}
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/44d5212750b01dd9.
Report an issue: GitHub.