pola-rs/polars · error · TypeError

Map requires a key and a value type, e.g. `pl.Map(pl.String,

Error message

Map requires a key and a value type, e.g. `pl.Map(pl.String, pl.Int64)`

What it means

When constructing a Series with an explicit Map dtype from a Python sequence, Polars requires the dtype to carry both a key and a value type (e.g. pl.Map(pl.String, pl.Int64)). A bare `pl.Map` has no key/value types, so the values cannot be converted and a TypeError is raised.

Source

Thrown at py-polars/src/polars/_utils/construction/series.py:203

            elif pyseries.dtype().is_integer() or pyseries.dtype() == Null:
                pyseries = pyseries.cast(
                    Decimal(scale=0), strict=strict, wrap_numerical=False
                )
            elif not isinstance(pyseries.dtype(), Decimal):
                msg = f"can't convert {pyseries.dtype()} to Decimal"
                raise TypeError(msg)

        return pyseries

    elif isinstance(dtype, Map):
        # A dict is otherwise inferred as a Struct, so the Map dtype has to drive this.
        return PySeries.new_from_any_values_and_dtype(
            name, values, dtype, strict=strict
        )

    elif dtype == Map:
        msg = "Map requires a key and a value type, e.g. `pl.Map(pl.String, pl.Int64)`"
        raise TypeError(msg)

    elif dtype == Struct:
        # This is very bad. Goes via rows? And needs to do outer nullability separate.
        # It also has two data passes.
        # TODO: eventually go into struct builder
        struct_schema = dtype.to_schema() if isinstance(dtype, Struct) else None
        empty = {}  # type: ignore[var-annotated]

        data = []
        invalid = []
        for i, v in enumerate(values):
            if v is None:
                invalid.append(i)
                data.append(empty)
            else:
                data.append(v)

        return plc.sequence_to_pydf(

View on GitHub (pinned to 68506541d2)

Solutions

  1. Instantiate the dtype with key and value types: use pl.Map(pl.String, pl.Int64) (or your key/value dtypes).
  2. If the data is a list of dicts, consider pl.List(pl.Struct({...})) instead — struct handles heterogeneous records and nullability better.
  3. Check the dtype is being read from configuration/schema with its parameters intact rather than just the class name.

Example fix

// before
s = pl.Series("m", [{"a": 1}], dtype=pl.Map)
// after
s = pl.Series("m", [{"a": 1}], dtype=pl.Map(pl.String, pl.Int64))
Defensive patterns

Strategy: type-guard

Validate before calling

import polars as pl
def is_instantiated_map(dtype) -> bool:
    return isinstance(dtype, pl.Map) and dtype is not pl.Map
def validate_map_dtype(dtype):
    if dtype is Map:
        raise TypeError("use pl.Map(key_dtype, value_dtype), not bare pl.Map")
    return dtype

Type guard

def is_parameterized_map(dtype) -> bool:
    return isinstance(dtype, pl.Map) and dtype is not pl.Map

Try / catch

try:
    s = pl.Series(name, values, dtype=dtype)
except TypeError as e:
    if "Map requires a key and a value type" in str(e):
        dtype = pl.Map(pl.String, pl.Int64)
        s = pl.Series(name, values, dtype=dtype)
    else:
        raise

Prevention

When it happens

Trigger: Calling pl.Series(name, values, dtype=pl.Map) (or any API that funnels into sequence_to_pyseries, such as DataFrame construction or __setitem__) with dtype equal to the bare Map class instead of an instantiated pl.Map(key_dtype, value_dtype).

Common situations: Passing `pl.Map` where other dtypes like pl.List or pl.Struct work bare; copying dtype declarations from docs without arguments; dynamically building dtypes from schema strings like 'map' without arguments.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of pola-rs/polars@68506541d2 (2026-09-10). Data as JSON: /api/errors/a19d4d3b6543f2e4. Report an issue: GitHub.