{"record":{"id":"44d5212750b01dd9","repo":"pola-rs/polars","slug":"mapping-item-must-be-a-datatype-or-datatype-expres","errorCode":null,"errorMessage":"mapping item must be a datatype or datatype expression; found {qualified_type_name(dtype_expr)!r}","messagePattern":"mapping item must be a datatype or datatype expression; found (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/functions/datatype.py","lineNumber":115,"sourceCode":"    \"\"\"\n    Create a new datatype expression that represents a Struct datatype.\n\n    .. warning::\n        This functionality is considered **unstable**. It may be changed\n        at any point without it being considered a breaking change.\n    \"\"\"\n    from polars._plr import PyDataTypeExpr\n\n    def preprocess(dtype_expr: PolarsDataType | pl.DataTypeExpr) -> PyDataTypeExpr:\n        if isinstance(dtype_expr, pl.DataType):\n            return dtype_expr.to_dtype_expr()._pydatatype_expr\n        if isinstance(dtype_expr, pl.DataTypeClass):\n            return dtype_expr.to_dtype_expr()._pydatatype_expr\n        elif isinstance(dtype_expr, pl.DataTypeExpr):\n            return dtype_expr._pydatatype_expr\n        else:\n            msg = f\"mapping item must be a datatype or datatype expression; found {qualified_type_name(dtype_expr)!r}\"\n            raise TypeError(msg)\n\n    fields = [(name, preprocess(dtype_expr)) for (name, dtype_expr) in mapping.items()]\n\n    return pl.DataTypeExpr._from_pydatatype_expr(\n        PyDataTypeExpr.struct_with_fields(fields)\n    )\n","sourceCodeStart":97,"sourceCodeEnd":122,"githubUrl":"https://github.com/pola-rs/polars/blob/df599052daf96e7a9cc30a3b0c6bd25d6947e3c0/py-polars/src/polars/functions/datatype.py#L97-L122","documentation":"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.","triggerScenarios":"pl.struct_with_fields({'a': 'Int64'}) or {'a': 'int'}; schemas deserialized from JSON/YAML config; numpy/pandas dtype objects; None values from optional fields.","commonSituations":"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.","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"],"exampleFix":"# before\npl.struct_with_fields({'a': 'Int64', 'b': 'String'})\n\n# after\npl.struct_with_fields({'a': pl.Int64, 'b': pl.String})\n\n# converting a string schema:\nfrom polars.datatypes import parse_into_dtype\npl.struct_with_fields({k: parse_into_dtype(v) for k, v in raw_schema.items()})","handlingStrategy":"type-guard","validationCode":"import polars as pl\nfrom polars.datatypes import parse_into_dtype\n\nclean = {\n    k: (v if isinstance(v, (pl.DataType, pl.DataTypeExpr)) else parse_into_dtype(v))\n    for k, v in raw_mapping.items()\n}\nexpr = pl.struct_with_fields(clean)","typeGuard":"def is_struct_field_dtype(x: object) -> bool:\n    return isinstance(x, (pl.DataType, pl.DataTypeExpr)) or (\n        isinstance(x, type) and hasattr(x, '__pl.TimeUnit__')\n    )","tryCatchPattern":null,"preventionTips":["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"],"tags":["polars","dtype","struct","typeerror","unstable-api"],"backgroundTag":null,"analyzedSha":"df599052daf96e7a9cc30a3b0c6bd25d6947e3c0","analyzedAt":"2026-08-16T12:10:03.978Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}