pola-rs/polars · error · InvalidOperationError

`pivot` needs either `index or `values` needs to be…

Error message

`pivot` needs either `index or `values` needs to be specified

What it means

This InvalidOperationError is raised by LazyFrame.pivot when neither `index` nor `values` is provided. The pivot needs at least one of these to know which columns stay as rows and which are aggregated; without either there is no well-defined output schema.

Solutions

  1. Pass `values=[...]` naming the columns to aggregate.
  2. Pass `index=[...]` naming the columns to keep as row identifiers (values then defaults to all remaining columns).
  3. Pass both `index` and `values` for full control of the pivot shape.

Example fix

// before
lf.pivot(on="date")
// after
lf.pivot(on="date", index="id", values="sales")
Defensive patterns

Strategy: validation

Validate before calling

if index is None and values is None:
    raise ValueError("pivot requires at least one of `index` or `values`")
out = lf.pivot(on=on, index=index, values=values)

Try / catch

from polars.exceptions import InvalidOperationError
try:
    out = lf.pivot(on=on, index=index, values=values)
except InvalidOperationError:
    out = lf.pivot(on=on, index=index or ["id"], values=values)

Prevention

When it happens

Trigger: Calling `LazyFrame.pivot(on=...)` with both `index=None` and `values=None`, so the code falls into the final `else` branch of the index/values resolution.

Common situations: Refactoring a DataFrame.pivot call to LazyFrame.pivot and dropping the `values` argument; dynamically building pivot kwargs from a config dict where both keys are absent.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of pola-rs/polars@fe841f959e (2026-09-18). Data as JSON: /api/errors/f798018947f82f83. Report an issue: GitHub.

Appendix: source

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

        ╞══════╪══════════╪══════════╡
        │ a    ┆ 0.998347 ┆ null     │
        │ b    ┆ 0.964028 ┆ 0.999954 │
        └──────┴──────────┴──────────┘
        """  # noqa: W505
        on_selector = parse_list_into_selector(on)

        if index is not None and values is not None:
            index_selector = parse_list_into_selector(index)
            values_selector = parse_list_into_selector(values)
        elif index is not None:
            index_selector = parse_list_into_selector(index)
            values_selector = cs.all() - on_selector - index_selector
        elif values is not None:
            values_selector = parse_list_into_selector(values)
            index_selector = cs.all() - on_selector - values_selector
        else:
            msg = "`pivot` needs either `index or `values` needs to be specified"
            raise InvalidOperationError(msg)

        agg = F.element()
        if isinstance(aggregate_function, str):
            if aggregate_function == "first":
                agg = agg.first()
            elif aggregate_function == "item":
                agg = agg.item()
            elif aggregate_function == "sum":
                agg = agg.sum()
            elif aggregate_function == "max":
                agg = agg.max()
            elif aggregate_function == "min":
                agg = agg.min()
            elif aggregate_function == "mean":
                agg = agg.mean()
            elif aggregate_function == "median":
                agg = agg.median()
            elif aggregate_function == "last":

View on GitHub (pinned to fe841f959e)