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

  1. Pass real dtypes: pl.struct_with_fields({'a': pl.Int64, 'b': pl.String})
  2. Convert string schemas first with polars.datatypes.parse_into_dtype in a dict comprehension
  3. For lazy per-column dtypes, combine dtype_of()/self_dtype() results, which are already DataTypeExprs
  4. 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

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


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