pola-rs/polars · error

cannot select columns using key of type

Error message

cannot select columns using key of type {qualified_type_name(key)!r}: {key!r}

What it means

Raised by Polars when the key passed to column selection is of a type that cannot be interpreted as column indices, a boolean mask, or column names. It is the fallback TypeError in _select_columns after all known key kinds (int, list, slice, Series, NumPy array of int/bool/str) have been ruled out.

Solutions

  1. Use an int for a single position, a list of ints for multiple positions, a list of str for names, or a bool mask/Series
  2. Convert the key to a supported form first, e.g. df[list(key)] for a set/tuple of labels or df[int(key)] for a float index
  3. If you meant to create columns, use df.with_columns(...) or assignment instead of df[key]

Example fix

// before
df[{"a": 1}]  # dict key -> TypeError
// after
df.select("a")  # or df["a"] for one column
Defensive patterns

Strategy: type-guard

Validate before calling

SUPPORTED = (int, slice, list, tuple, range, pl.Series)
assert isinstance(key, SUPPORTED), f"unsupported column key type: {type(key)}"

Type guard

def is_valid_column_key(key) -> bool:
    import polars as pl
    if isinstance(key, (int, slice, range, pl.Series)):
        return True
    if isinstance(key, (list, tuple)):
        return all(isinstance(v, (int, str, bool)) for v in key)
    try:
        import numpy as np
        return isinstance(key, np.ndarray) and key.dtype.kind in ("i", "u", "b", "U")
    except ImportError:
        return False

Try / catch

try:
    out = df[key]
except TypeError as e:
    if "cannot select columns" in str(e):
        out = df[list(key)] if hasattr(key, "__iter__") else df.select(str(key))
    else:
        raise

Prevention

When it happens

Trigger: df[{'a': 1}] (dict), df[0.5] (float), df[(lambda x: x)] — any non-supported key type passed where columns are selected, e.g. df[my_tuple_of_floats].

Common situations: Accidentally passing a dict (intending to assign/rename) via __getitem__; passing a float column position instead of int; passing a set (unordered) of labels; migrating pandas code where a tuple key had different semantics.

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@fe841f959e (2026-09-18). Data as JSON: /api/errors/a78f807c11c4ab02. Report an issue: GitHub.

Appendix: source

Thrown at py-polars/src/polars/_utils/getitem.py:260

        if len(key) == 0:
            return df.__class__()

        dtype_kind = key.dtype.kind
        if dtype_kind in ("i", "u"):
            return _select_columns_by_index(df, key)
        elif dtype_kind == "b":
            return _select_columns_by_mask(df, key)
        elif isinstance(key[0], str):
            return _select_columns_by_name(df, key)
        else:
            msg = f"cannot select columns using NumPy array of type {key.dtype}"
            raise TypeError(msg)

    msg = (
        f"cannot select columns using key of type {qualified_type_name(key)!r}: {key!r}"
    )
    raise TypeError(msg)


def _select_columns_by_index(df: DataFrame, key: Iterable[int]) -> DataFrame:
    series = [df.to_series(i) for i in key]
    return df.__class__(series)


def _select_columns_by_name(df: DataFrame, key: Iterable[str]) -> DataFrame:
    return df._from_pydf(df._df.select(list(key)))


def _select_columns_by_mask(
    df: DataFrame, key: Sequence[bool] | Series | np.ndarray[Any, Any]
) -> DataFrame:
    if len(key) != df.width:
        msg = f"expected {df.width} values when selecting columns by boolean mask, got {len(key)}"
        raise ValueError(msg)

View on GitHub (pinned to fe841f959e)