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.htmlView on GitHub (pinned to df599052da)
Solutions
- Use a list key for column(s): `df[['a','b']] = np.array_2d` or `df['a'] = pl.Series(...)` via with_columns
- For scalar cell assignment use the tuple form: `df[row_idx, col_idx_or_name] = value`
- For boolean/int row selection, rewrite as `df = df.with_columns(pl.when(mask).then(v).otherwise(pl.col(c)))`
- 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
- Never translate pandas boolean/int-key assignments literally; rewrite as with_columns
- Wrap dataframe assignment in a helper that whitelists str, list[str], and (row, col) tuples
- Convert numpy scalar keys (np.int64 etc.) to plain int/str before indexing
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
- unexpected column selection {col_selection!r}
- the truth value of a DataFrame is ambiguous Hint: to check
- DataFrame object does not support `Series` assignment by ind
- can only set multiple columns with 2D matrix
- not allowed to set DataFrame by boolean mask in the row posi
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/74104eb6eaf4db2a.
Report an issue: GitHub.