pola-rs/polars · error · TypeError

invalid dtype

Error message

invalid dtype: {t!r}

What it means

cs.by_dtype() validates every element of any collection passed to it: each must be a Polars dtype or a mappable builtin type. An element failing that check raises this TypeError naming the offending item. This is the per-element branch; the scalar branch is error 709.

Solutions

  1. Replace each invalid element with a polars dtype: 'float' -> pl.Float64.
  2. Normalize with a mapping helper before the call: [DTYPES[d] if isinstance(d, str) else d for d in items].
  3. Validate elements: all(is_polars_dtype(t) or isinstance(t, type) for t in items).
  4. Convert foreign dtypes (pandas/numpy) to polars dtypes explicitly.

Example fix

// before
cs.by_dtype([pl.Int64, "float"])
// after
cs.by_dtype([pl.Int64, pl.Float64])
Defensive patterns

Strategy: validation

Validate before calling

from polars.datatypes import is_polars_dtype
bad = [t for t in dtype_collection if not (is_polars_dtype(t) or isinstance(t, type))]
assert not bad, f"invalid dtype elements: {bad!r}"

Type guard

def all_dtype_like(items) -> bool:
    from polars.datatypes import is_polars_dtype
    return all(is_polars_dtype(t) or isinstance(t, type) for t in items)

Try / catch

try:
    sel = cs.by_dtype(*dtype_collection)
except TypeError as e:
    if e.args and e.args[0].startswith("invalid dtype:"):
        dtype_collection = [DTYPE_MAP.get(t, t) for t in dtype_collection]
        sel = cs.by_dtype(*dtype_collection)
    else:
        raise

Prevention

When it happens

Trigger: cs.by_dtype([pl.Int64, 3.14]) or cs.by_dtype((pl.String, 'utf8')) — a numeric, string, or None element inside the iterable.

Common situations: Dtype lists loaded from JSON/YAML where everything deserialized as strings; mixing pandas/numpy dtype objects into a polars dtype list; set literal containing a stray non-dtype value.

Related errors


AI-assisted analysis of pola-rs/polars@fe841f959e (2026-09-18). Data as JSON: /api/errors/53496cbf6b8326d9. Report an issue: GitHub.

Appendix: source

Thrown at py-polars/src/polars/selectors.py:1086

    shape: (2, 2)
    ┌───────┬──────────┐
    │ other ┆ value    │
    │ ---   ┆ ---      │
    │ str   ┆ i64      │
    ╞═══════╪══════════╡
    │ bar   ┆ 5000555  │
    │ foo   ┆ -3265500 │
    └───────┴──────────┘
    """
    all_dtypes: builtins.list[PolarsDataType | PythonDataType] = []
    for tp in dtypes:
        if is_polars_dtype(tp) or isinstance(tp, type):
            all_dtypes.append(tp)
        elif isinstance(tp, Collection):
            for t in tp:
                if not (is_polars_dtype(t) or isinstance(t, type)):
                    msg = f"invalid dtype: {t!r}"
                    raise TypeError(msg)
                all_dtypes.append(t)
        else:
            msg = f"invalid dtype: {tp!r}"
            raise TypeError(msg)

    return Selector._by_dtype(all_dtypes)


def by_index(
    *indices: int | range | Sequence[int | range], require_all: bool = True
) -> Selector:
    """
    Select all columns matching the given indices (or range objects).

    Parameters
    ----------
    *indices
        One or more column indices (or range objects).

View on GitHub (pinned to fe841f959e)