pola-rs/polars · error
cannot set Series of dtype: {self.dtype!r} with list/tuple a
Error message
cannot set Series of dtype: {self.dtype!r} with list/tuple as value; use a scalar value What it means
Raised by Series.__setitem__ when you assign a list/tuple value to a Series whose dtype is not numeric or temporal. For numeric/temporal dtypes Polars scatters the sequence element-wise, but for String, List, Struct, Categorical, etc. there is no vector path, so it demands a scalar value instead.
Source
Thrown at py-polars/src/polars/series/series.py:1547
[
10
99
99
]
"""
# do the single idx as first branch as those are likely in a tight loop
if isinstance(key, int) and not isinstance(key, bool):
self.scatter(key, value)
return None
elif isinstance(value, Sequence) and not isinstance(value, str):
if self.dtype.is_numeric() or self.dtype.is_temporal():
self.scatter(key, value) # type: ignore[arg-type]
return None
msg = (
f"cannot set Series of dtype: {self.dtype!r} with list/tuple as value;"
" use a scalar value"
)
raise TypeError(msg)
if isinstance(key, Series):
if key.dtype == Boolean:
self._s = self.set(key, value)._s
elif key.dtype.is_integer():
self._s = self.scatter(key, value)._s
else:
msg = f"cannot use Series of dtype {key.dtype!r} for indexing; expected boolean or integer dtype"
raise TypeError(msg)
# TODO: implement for these types without casting to series
elif _check_for_numpy(key) and isinstance(key, np.ndarray):
if key.dtype == np.bool_:
# boolean numpy mask
self._s = self.scatter(np.argwhere(key)[:, 0], value)._s
else:
s = self._from_pyseries(
PySeries.new_u32("", np.array(key, np.uint32), _strict=True)
)View on GitHub (pinned to df599052da)
Solutions
- Assign a scalar: `s[0] = 'x'`.
- For multiple positions on non-numeric dtypes, loop scalars or rebuild the Series: `pl.Series(name, new_values, dtype=s.dtype)`.
- For many updates, prefer expression-based replacement: `s.set_at_idx(idx, values)` (check dtype support) or `s.zip_with(mask, other)`.
- If the column is genuinely numeric/temporal, check that it was not mis-typed as String during inference.
Example fix
// before
s = pl.Series(['a', 'b', 'c'])
s[[0, 2]] = ['x', 'z'] # TypeError
// after
for i, v in zip([0, 2], ['x', 'z']):
s[i] = v
# or rebuild:
pl.Series(s.name, ['x', 'b', 'z']) Defensive patterns
Strategy: validation
Validate before calling
def setitem_value_ok(s: pl.Series, value) -> bool:
if isinstance(value, (list, tuple)) and not isinstance(value, str):
return s.dtype.is_numeric() or s.dtype.is_temporal()
return True
assert setitem_value_ok(s, ['x', 'y']), 'use a scalar for this dtype' Type guard
def accepts_sequence_value(s: pl.Series) -> bool:
return s.dtype.is_numeric() or s.dtype.is_temporal() Try / catch
try:
s[key] = value
except TypeError as e:
if 'list/tuple as value' not in str(e):
raise
for i, v in zip(indices, value):
s[i] = v Prevention
- Only assign scalars to String/Categorical/List/Struct Series.
- Batch updates are better expressed as rebuilding the Series or pl.when/then in a frame.
- Watch for accidental list-wrapping: s[0] = ['x'] instead of s[0] = 'x'.
When it happens
Trigger: `s = pl.Series(['a','b','c']); s[[0,1]] = ['x','y']`, `s[0] = ['x']`, `s[mask] = ('p','q')` on a String/Categorical/List/Struct-typed Series. Numeric and temporal Series accept sequences fine (scatter branch just above).
Common situations: Pandas-style multi-cell assignment (`df['col'][[0,1]] = [...]`) ported to Polars; updating string label columns in a loop-free batch; setting a single element but wrapping the value in a list by accident (`s[0] = ['x']` instead of `s[0] = 'x'`).
Related errors
- cannot use Series of dtype {key.dtype!r} for indexing; expec
- cannot compare datetime.datetime to Series of type {self.dty
- cannot do arithmetic with Series of dtype: {self.dtype!r} an
- first cast to integer before dividing datelike dtypes
- first cast to integer before multiplying datelike dtypes
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/d25b24eece7925ce.
Report an issue: GitHub.