pola-rs/polars · error · TypeError

cannot use `__setitem__` on DataFrame with key {key!r} of ty

Error message

cannot use `__setitem__` on DataFrame with key {key!r} of type {type(key).__name__!r} and value {value!r} of type {type(value).__name__!r}

What it means

Raised by DataFrame.__setitem__ when the key is not one of the three supported shapes: a str (single column), a list of column names, or a (row, col) tuple. Polars intentionally keeps __setitem__ minimal — pandas-style int positional keys, boolean/int Series keys, slices, and ndarrays are all rejected with this TypeError instead of being silently interpreted. The message echoes both the key and value types so you can see which unsupported shape you used.

Source

Thrown at py-polars/src/polars/dataframe/frame.py:1605

                raise TypeError(msg)

            # dispatch to __setitem__ of Series to do modification
            s[row_selection] = value

            # now find the location to place series
            # df[idx]
            if isinstance(col_selection, int):
                self.replace_column(col_selection, s)
            # df["foo"]
            elif isinstance(col_selection, str):
                self._replace(col_selection, s)
        else:
            msg = (
                f"cannot use `__setitem__` on DataFrame"
                f" with key {key!r} of type {type(key).__name__!r}"
                f" and value {value!r} of type {type(value).__name__!r}"
            )
            raise TypeError(msg)

    def __len__(self) -> int:
        return self.height

    def __copy__(self) -> DataFrame:
        return self.clone()

    def __deepcopy__(self, memo: None = None) -> DataFrame:
        return self.clone()

    def _ipython_key_completions_(self) -> list[str]:
        return self.columns

    def __arrow_c_stream__(self, requested_schema: object | None = None) -> object:
        """
        Export a DataFrame via the Arrow PyCapsule Interface.

        https://arrow.apache.org/docs/dev/format/CDataInterface/PyCapsuleInterface.html

View on GitHub (pinned to df599052da)

Solutions

  1. Use a list key for column(s): `df[['a','b']] = np.array_2d` or `df['a'] = pl.Series(...)` via with_columns
  2. For scalar cell assignment use the tuple form: `df[row_idx, col_idx_or_name] = value`
  3. For boolean/int row selection, rewrite as `df = df.with_columns(pl.when(mask).then(v).otherwise(pl.col(c)))`
  4. Convert numpy/python scalars to plain str/int and sequences to list before indexing

Example fix

# before
df[pl.Series([True, False, True])] = 0

# after
df = df.with_columns(
    pl.when(pl.Series([True, False, True])).then(0).otherwise(pl.col(c)).keep_name()
    for c in df.columns
)
Defensive patterns

Strategy: type-guard

Validate before calling

def supported_setitem_key(key: object) -> bool:
    if isinstance(key, str):
        return True
    if isinstance(key, list):
        return all(isinstance(k, str) for k in key)
    return isinstance(key, tuple) and len(key) == 2 and not isinstance(key[0], bool)

Type guard

def is_setitem_key_ok(key: object) -> bool:
    """DataFrame.__setitem__ only accepts str, list[str], or 2-tuples."""
    return (
        isinstance(key, str)
        or (isinstance(key, list) and all(isinstance(k, str) for k in key))
        or (isinstance(key, tuple) and len(key) == 2)
    )

Try / catch

try:
    df[key] = value
except TypeError as e:
    if 'cannot use `__setitem__`' in str(e):
        df = df.with_columns(...set via expressions...)
    else:
        raise

Prevention

When it happens

Trigger: `df[0] = value` (int key), `df[pl.Series([True,False])] = 5`, `df[1:] = ...` (slice key), `df[np.array([1,2])] = ...`, or `df[('a',)] = x` (1-tuple). Note a str key alone also fails earlier with a different 'Series assignment' TypeError; this branch catches everything that is not str/list/tuple.

Common situations: Translating pandas muscle memory like `df[0] = ...` or boolean masking `df[df['a'] > 1] = 0`; passing a numpy int as key (np.int64 is not a Python int and misses isinstance checks on some paths); generators/tuples used as column keys instead of lists.

Related errors


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