pola-rs/polars · error · TypeError

cannot select rows using key of type {qualified_type_name(ke

Error message

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

What it means

Row-selector branch of DataFrame.__getitem__ (getitem.py:328). In df[rows, cols] the first slot is parsed by _select_rows, which accepts int, slice, range, Sequence (converted to indices), pl.Series, and np.ndarray; anything else raises this TypeError. For single keys df[k], _select_rows is tried first and its TypeError triggers a fallback to column selection (error 40), so this message mainly escapes from the explicit two-slot form df[rows, cols].

Source

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

        if not key:
            return df.clear()
        if isinstance(key[0], bool):
            _raise_on_boolean_mask()
        s = pl.Series("", key, dtype=Int64)
        indices = _convert_series_to_indices(s, df.height)
        return _select_rows_by_index(df, indices)

    elif isinstance(key, pl.Series):
        indices = _convert_series_to_indices(key, df.height)
        return _select_rows_by_index(df, indices)

    elif _check_for_numpy(key) and isinstance(key, np.ndarray):
        indices = _convert_np_ndarray_to_indices(key, df.height)
        return _select_rows_by_index(df, indices)

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


def _select_rows_by_slice(df: DataFrame, key: slice) -> DataFrame:
    return PolarsSlice(df).apply(key)  # type: ignore[return-value]


def _select_rows_by_index(df: DataFrame, key: Series) -> DataFrame:
    return df._from_pydf(df._df.gather_with_series(key._s))


# UTILS


def _convert_series_to_indices(s: Series, size: int) -> Series:
    """Convert a Series to indices, taking into account negative values."""
    # Unsigned or signed Series (ordered from fastest to slowest).
    #   - pl.UInt32 (polars) or pl.UInt64 (polars_u64_idx) Series indexes.
    #   - Other unsigned Series indexes are converted to pl.UInt32 (polars)

View on GitHub (pinned to df599052da)

Solutions

  1. Normalize scalars: df[int(idx), 'a'] or df[np_val.item(), 'a']
  2. Use explicit methods: df.row(i, named=True) for one row, df.slice(...) for ranges
  3. Pass a list/Series/1D numpy array of ints for multiple rows: df[[0, 2], 'a']

Example fix

# before
df[np.int64(2), "a"]   # numpy scalar is not int

# after
df[int(np.int64(2)), "a"]
Defensive patterns

Strategy: type-guard

Validate before calling

from collections.abc import Sequence
import polars as pl

try:
    import numpy as np
    _ND = (np.ndarray,)
except ImportError:
    _ND = ()

if not isinstance(row_key, (int, slice, range, Sequence, pl.Series) + _ND):
    row_key = int(row_key)  # normalize scalars; will raise clearly if impossible
df[row_key, "a"]

Type guard

def is_valid_row_key(key: object) -> bool:
    import polars as pl
    from collections.abc import Sequence
    return isinstance(key, (int, slice, range, Sequence, pl.Series))

Prevention

When it happens

Trigger: df[{0: 'x'}, :] (dict row key); df[3.0, 'a'] (float index); df[np.int64(2), 'a'] (numpy scalar, not Python int); df[None, 'a']; df[some_object, :].

Common situations: Passing floats or numpy scalars produced by computations as the row slot; assuming pandas .loc-style label/dict keys work on polars; mixing up row-first tuple semantics.

Related errors


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