pola-rs/polars · error · ValueError

negative slice lengths ({length!r}) are invalid for LazyFram

Error message

negative slice lengths ({length!r}) are invalid for LazyFrame

What it means

LazyFrame.slice() (and head/limit which build on slicing) rejects negative lengths: unlike DataFrame, lazy frames cannot express 'all but the last N rows' cheaply because row count is unknown until execution. A negative length raises ValueError.

Source

Thrown at py-polars/src/polars/lazyframe/frame.py:7208

        ...         "a": ["x", "y", "z"],
        ...         "b": [1, 3, 5],
        ...         "c": [2, 4, 6],
        ...     }
        ... )
        >>> lf.slice(1, 2).collect()
        shape: (2, 3)
        ┌─────┬─────┬─────┐
        │ a   ┆ b   ┆ c   │
        │ --- ┆ --- ┆ --- │
        │ str ┆ i64 ┆ i64 │
        ╞═════╪═════╪═════╡
        │ y   ┆ 3   ┆ 4   │
        │ z   ┆ 5   ┆ 6   │
        └─────┴─────┴─────┘
        """
        if length and length < 0:
            msg = f"negative slice lengths ({length!r}) are invalid for LazyFrame"
            raise ValueError(msg)
        return self._from_pyldf(self._ldf.slice(offset, length))

    def limit(self, n: int = 5) -> LazyFrame:
        """
        Get the first `n` rows.

        Alias for :func:`LazyFrame.head`.

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

        Parameters
        ----------
        n
            Number of rows to return.

        Examples
        --------
        >>> lf = pl.LazyFrame(

View on GitHub (pinned to df599052da)

Solutions

  1. Clamp the length: length = max(0, length) before slicing
  2. Use lf.collect() first if negative slicing semantics (drop last rows) are genuinely needed, then slice the DataFrame
  3. Compute lengths from known row counts only after collecting
  4. Use tail()/head() with non-negative counts

Example fix

# before
lf2 = lf.slice(0, requested - reserved)  # may be negative

# after
lf2 = lf.slice(0, max(0, requested - reserved))
Defensive patterns

Strategy: validation

Validate before calling

length = max(0, length) if length is not None else None
lf2 = lf.slice(offset, length)

Type guard

def is_non_negative_length(length) -> bool:
    return length is None or length >= 0

Prevention

When it happens

Trigger: lf.slice(0, -5); lf.head(-1); length computed as n - total where it goes negative for small frames; code ported from pandas/DataFrame where negative slicing is allowed.

Common situations: Pagination/windowing logic with computed lengths; take(N-k) style calculations on frames smaller than k; reusable code shared between DataFrame and LazyFrame.

Related errors


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