pola-rs/polars · error

cannot select elements using key of type

Error message

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

What it means

This is the fallback raise at the end of get_series_item_by_key: the key given to Series.__getitem__ matched none of the supported kinds (int, slice, bool mask, Sequence of ints, pl.Series of indices/mask, numpy 1-D int/bool array). Polars raises TypeError naming the key's type and repr so the caller can see exactly what was unsupported.

Solutions

  1. Convert the key to an int list or numpy int array before indexing: s[list(key)].
  2. Wrap the key in pl.Series(indices, dtype=Int64) if it is an iterable of ints.
  3. For boolean selection, pass a pl.Series or numpy bool array, not a set/dict.
  4. Check for None keys and use a default (e.g. slice(None)) before indexing.
  5. Use s.gather(indices) or s.filter(mask) as explicit alternatives.

Example fix

// before
s[{0, 2}]
// after
s[list({0, 2})]
Defensive patterns

Strategy: type-guard

Validate before calling

def valid_series_key(key):
    return (isinstance(key, (int, slice)) or
            (hasattr(key, 'dtype') and hasattr(key, 'to_list')) or
            (isinstance(key, (list, tuple)) and all(isinstance(x, int) for x in key)) or
            (type(key).__module__ == 'numpy' and getattr(key, 'ndim', 2) == 1))
assert valid_series_key(k), f'unsupported Series key: {type(k)}'

Type guard

def is_selectable_key(key: object) -> bool:
    import numpy as np
    import polars as pl
    return (isinstance(key, (int, slice))
            or isinstance(key, (pl.Series, list, tuple))
            or isinstance(key, np.ndarray) and key.ndim <= 1)

Try / catch

try:
    out = series[key]
except TypeError as e:
    if 'cannot select elements using key' in str(e):
        out = series[list(key)] if hasattr(key, '__iter__') else series[0]
    else:
        raise

Prevention

When it happens

Trigger: s[{'a': 1}]; s[frozenset({0, 1})]; s[some_generator]; s[None]; s[np 2-D array] (handled by ndarray path only if convertible); any custom object passed as Series index.

Common situations: Passing a dict mapping from pandas-style label lookup; forgetting to convert a generator or set to a list; passing a 2-D numpy array of indices; passing None after an upstream function returned an optional key.

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/eb63ed325abdf609. Report an issue: GitHub.

Appendix: source

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

        try:
            indices = pl.Series("", key, dtype=Int64)
        except TypeError:
            msg = f"cannot select elements using Sequence with elements of type {qualified_type_name(first)!r}"
            raise TypeError(msg) from None

        indices = _convert_series_to_indices(indices, s.len())
        return _select_elements_by_index(s, indices)

    elif isinstance(key, pl.Series):
        indices = _convert_series_to_indices(key, s.len())
        return _select_elements_by_index(s, indices)

    elif _check_for_numpy(key) and isinstance(key, np.ndarray):
        indices = _convert_np_ndarray_to_indices(key, s.len())
        return _select_elements_by_index(s, indices)

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


def _select_elements_by_slice(s: Series, key: slice) -> Series:
    return PolarsSlice(s).apply(key)  # type: ignore[return-value]


def _select_elements_by_index(s: Series, key: Series) -> Series:
    return s._from_pyseries(s._s.gather_with_series(key._s))


# `str` overlaps with `Sequence[str]`
# We can ignore this but we must keep this overload ordering
@overload
def get_df_item_by_key(
    df: DataFrame, key: tuple[SingleIndexSelector, SingleColSelector]
) -> Any: ...

View on GitHub (pinned to fe841f959e)