pola-rs/polars · error · CopyNotAllowedError
unevenly chunked columns must be rechunked
Error message
unevenly chunked columns must be rechunked
What it means
Raised while slicing an interchange frame into chunks aligned with the first column's chunk boundaries. If the row slice has columns with more than one chunk each (uneven or multi-chunk columns), Polars must call rechunk() on the slice, which copies memory; when the interchange object was created with allow_copy=False, CopyNotAllowedError (a RuntimeError) is raised instead.
Solutions
- Rechunk the source first: df = df.rechunk() before creating the interchange object with allow_copy=False.
- Allow copies: create the interchange object with __dataframe__(allow_copy=True) (the default).
- In consumer code, catch CopyNotAllowedError and retry the operation with allow_copy=True.
Example fix
# before icdf = df.__dataframe__(allow_copy=False) # CopyNotAllowedError when columns are chunked # after icdf = df.rechunk().__dataframe__(allow_copy=False) # or simply allow the copy: icdf = df.__dataframe__(allow_copy=True)
Defensive patterns
Strategy: fallback
Validate before calling
if df.n_chunks() > 1: # uneven or multi-chunk columns force a rechunk copy
df = df.rechunk()
icdf = df.__dataframe__(allow_copy=False) Try / catch
from polars.interchange.protocol import CopyNotAllowedError
try:
icdf = df.__dataframe__(allow_copy=False)
chunks = list(icdf.get_chunks())
except CopyNotAllowedError:
icdf = df.rechunk().__dataframe__(allow_copy=True)
chunks = list(icdf.get_chunks()) Prevention
- Rechunk (or pl.concat(..., rechunk=True)) any frame before a zero-copy interchange handoff.
- Check df.n_chunks('all') in tests to catch uneven chunk layouts early.
- Reserve allow_copy=False for single-chunk frames; treat CopyNotAllowedError as the signal to relax it.
When it happens
Trigger: Iterating icdf.get_chunks() (or get_columns path) on a PolarsDataFrame created via df.__dataframe__(allow_copy=False) or PolarsDataFrame(df, allow_copy=False) where the frame's columns are chunked or unevenly chunked — typical after pl.concat/hstack of separately built Series, or after chunked scans without rechunk.
Common situations: Zero-copy pipelines that set allow_copy=False to guarantee no allocation; frames assembled from multiple sources where each column carries its own chunk layout; per-column chunk counts differing (df.n_chunks('all') not all 1).
Related errors
- bitmask must be constructed
- bitmask must be inverted
- byte-packed boolean buffer must be converted to bit-packed…
- bytemask must be converted into a bitmask
- data buffer must be cast from
AI-assisted analysis of pola-rs/polars@9b5d73fd00 (2026-08-19).
Data as JSON: /api/errors/ea8e0ba3b778dd98.
Report an issue: GitHub.
Appendix: source
Thrown at py-polars/src/polars/interchange/dataframe.py:227
def _get_chunks_from_col_chunks(self) -> Iterator[DataFrame]:
"""
Return chunks of this dataframe according to the chunks of the first column.
If columns are not all chunked identically, they will be rechunked like the
first column. If copy is not allowed, this raises a RuntimeError.
"""
col_chunks = self.get_column(0).get_chunks()
chunk_sizes = [chunk.size() for chunk in col_chunks]
starts = [0] + list(accumulate(chunk_sizes))
for i in range(len(starts) - 1):
start, end = starts[i : i + 2]
chunk = self._df[start:end, :]
if not all(x == 1 for x in chunk.n_chunks("all")):
if not self._allow_copy:
msg = "unevenly chunked columns must be rechunked"
raise CopyNotAllowedError(msg)
chunk = chunk.rechunk()
yield chunk
View on GitHub (pinned to 9b5d73fd00)