pola-rs/polars · error · TypeError

'length' must be an integer, string, or expression, not {typ

Error message

'length' must be an integer, string, or expression, not {type(length).__name__}

What it means

The companion check in Expr.list.slice for `length`: like offset, it must be an int, str (column name), or Expr; any non-str Collection (list/tuple/set/dict) raises TypeError naming the actual type. It is only checked when length is not None, since None means 'slice to the end'.

Source

Thrown at py-polars/src/polars/expr/list.py:1139

        ┌─────────────┬───────────┐
        │ a           ┆ slice     │
        │ ---         ┆ ---       │
        │ list[i64]   ┆ list[i64] │
        ╞═════════════╪═══════════╡
        │ [1, 2, … 4] ┆ [2, 3]    │
        │ [10, 2, 1]  ┆ [2, 1]    │
        └─────────────┴───────────┘
        """
        if isinstance(offset, Collection) and not isinstance(offset, str):
            msg = f"'offset' must be an integer, string, or expression, not {type(offset).__name__}"
            raise TypeError(msg)
        if (
            length is not None
            and isinstance(length, Collection)
            and not isinstance(length, str)
        ):
            msg = f"'length' must be an integer, string, or expression, not {type(length).__name__}"
            raise TypeError(msg)

        offset_pyexpr = parse_into_expression(offset)
        length_pyexpr = parse_into_expression(length)
        return wrap_expr(self._pyexpr.list_slice(offset_pyexpr, length_pyexpr))

    def head(self, n: int | str | Expr = 5) -> Expr:
        """
        Slice the first `n` values of every sub-list.

        .. engine-support:: in-memory, streaming, distributed

        Parameters
        ----------
        n
            Number of values to return for each sublist.

        Examples
        --------

View on GitHub (pinned to df599052da)

Solutions

  1. Constant length: list.slice(1, 2).
  2. Per-row lengths: list.slice(1, pl.col('lens')) after adding them as a column.
  3. Fix defaults: use None, not [], for 'unspecified'.

Example fix

# before
pl.col('l').list.slice(1, length=[2, 1])

# after
pl.col('l').list.slice(1, 2)
# per-row:
df.with_columns(pl.col('l').list.slice(pl.col('offs'), pl.col('lens')))
Defensive patterns

Strategy: type-guard

Validate before calling

from collections.abc import Collection
if length is not None and isinstance(length, Collection) and not isinstance(length, str):
    raise TypeError(f'length must be int/str/Expr, got {type(length).__name__}')

Type guard

from collections.abc import Collection

def is_valid_length(v) -> bool:
    return v is None or isinstance(v, (int, str)) or hasattr(v, '_pyexpr')

Prevention

When it happens

Trigger: pl.col('l').list.slice(1, [2, 1]) — passing per-row lengths as a Python list; wrappers accepting Sequence[int] for lengths.

Common situations: Per-row length lists intended elementwise but not materialised as a column; defaulting length to an empty list instead of None; adapting offset fixes while forgetting length has the same rule.

Related errors


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