{"record":{"id":"f798018947f82f83","repo":"pola-rs/polars","slug":"pivot-needs-either-index-or-values-needs-to-b","errorCode":null,"errorMessage":"`pivot` needs either `index or `values` needs to be specified","messagePattern":"`pivot` needs either `index or `values` needs to be specified","errorType":"exception","errorClass":"InvalidOperationError","httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/lazyframe/frame.py","lineNumber":8651,"sourceCode":"        ╞══════╪══════════╪══════════╡\n        │ a    ┆ 0.998347 ┆ null     │\n        │ b    ┆ 0.964028 ┆ 0.999954 │\n        └──────┴──────────┴──────────┘\n        \"\"\"  # noqa: W505\n        on_selector = parse_list_into_selector(on)\n\n        if index is not None and values is not None:\n            index_selector = parse_list_into_selector(index)\n            values_selector = parse_list_into_selector(values)\n        elif index is not None:\n            index_selector = parse_list_into_selector(index)\n            values_selector = cs.all() - on_selector - index_selector\n        elif values is not None:\n            values_selector = parse_list_into_selector(values)\n            index_selector = cs.all() - on_selector - values_selector\n        else:\n            msg = \"`pivot` needs either `index or `values` needs to be specified\"\n            raise InvalidOperationError(msg)\n\n        agg = F.element()\n        if isinstance(aggregate_function, str):\n            if aggregate_function == \"first\":\n                agg = agg.first()\n            elif aggregate_function == \"item\":\n                agg = agg.item()\n            elif aggregate_function == \"sum\":\n                agg = agg.sum()\n            elif aggregate_function == \"max\":\n                agg = agg.max()\n            elif aggregate_function == \"min\":\n                agg = agg.min()\n            elif aggregate_function == \"mean\":\n                agg = agg.mean()\n            elif aggregate_function == \"median\":\n                agg = agg.median()\n            elif aggregate_function == \"last\":","sourceCodeStart":8633,"sourceCodeEnd":8669,"githubUrl":"https://github.com/pola-rs/polars/blob/df599052daf96e7a9cc30a3b0c6bd25d6947e3c0/py-polars/src/polars/lazyframe/frame.py#L8633-L8669","documentation":"LazyFrame.pivot() requires at least one of index= or values= to be given (on= is mandatory separately). If neither is provided, polars cannot decide which columns become the row identifiers versus the pivoted values, and raises InvalidOperationError. When only one is given, the other is inferred as the complement of the on= columns.","triggerScenarios":"lf.pivot(on='metric', values=... missing and index missing); dynamic pipelines where index/values come from config that is empty; porting DataFrame.pivot calls that had different parameter requirements.","commonSituations":"Config-driven reshaping jobs; wide/long transformations where the caller assumed column inference from on= alone.","solutions":["Pass index=['id'] to identify output rows, letting values default to all remaining non-on columns","Or pass values=['val'] to pivot explicitly, letting index default to the complement","Validate config: require at least one of index/values before calling pivot","Check for typos — the argument names are exactly 'index' and 'values'"],"exampleFix":"# before\nwide = lf.pivot(on='month')\n\n# after\nwide = lf.pivot(on='month', index='id', aggregate_function='sum')","handlingStrategy":"validation","validationCode":"if index is None and values is None:\n    index = ['id']  # sensible default row identifier\nwide = lf.pivot(on=on, index=index, values=values, aggregate_function=aggregate_function)","typeGuard":"def has_pivot_axes(index, values) -> bool:\n    return index is not None or values is not None","tryCatchPattern":"try:\n    wide = lf.pivot(on='month')\nexcept Exception:\n    wide = lf.pivot(on='month', index='id', aggregate_function='sum')","preventionTips":["Always pass index= explicitly in config-driven pivots","Validate reshape config before running the pipeline","Remember on= is required and handles column grouping, not row identity"],"tags":["polars","lazyframe","pivot","reshape","missing-argument"],"backgroundTag":null,"analyzedSha":"df599052daf96e7a9cc30a3b0c6bd25d6947e3c0","analyzedAt":"2026-08-16T12:10:03.978Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}