{"record":{"id":"20c20d0c923c9c75","repo":"pola-rs/polars","slug":"expected-polars-expression-or-object-convertible-t","errorCode":null,"errorMessage":"Expected Polars expression or object convertible to one, got {type(value)}.\n\nHint: if you tried\n    group_by(by={value!r})\nthen you probably want to use this instead:\n    group_by({value!r})","messagePattern":"Expected Polars expression or object convertible to one, got (.+?)\\.\n\nHint: if you tried\n    group_by\\(by=(.+?)\\)\nthen you probably want to use this instead:\n    group_by\\((.+?)\\)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/lazyframe/frame.py","lineNumber":5053,"sourceCode":"        │ a   ┆ b   ┆ c   │\n        │ --- ┆ --- ┆ --- │\n        │ str ┆ i64 ┆ f64 │\n        ╞═════╪═════╪═════╡\n        │ a   ┆ 0   ┆ 4.0 │\n        │ b   ┆ 1   ┆ 3.0 │\n        │ c   ┆ 1   ┆ 1.0 │\n        └─────┴─────┴─────┘\n        \"\"\"\n        for value in named_by.values():\n            if not isinstance(value, (str, pl.Expr, pl.Series)):\n                msg = (\n                    f\"Expected Polars expression or object convertible to one, got {type(value)}.\\n\\n\"\n                    \"Hint: if you tried\\n\"\n                    f\"    group_by(by={value!r})\\n\"\n                    \"then you probably want to use this instead:\\n\"\n                    f\"    group_by({value!r})\"\n                )\n                raise TypeError(msg)\n        exprs = parse_into_list_of_expressions(*by, **named_by)\n        lgb = self._ldf.group_by(exprs, maintain_order)\n        return LazyGroupBy(lgb)\n\n    @removed_parameters(\n        RenamedParameter(\n            name=\"by\",\n            new_name=\"group_by\",\n            deprecated_in=\"0.20.14\",\n            removed_in=\"2.0\",\n        )\n    )\n    def rolling(\n        self,\n        index_column: IntoExpr,\n        *,\n        period: str | timedelta,\n        offset: str | timedelta | None = None,","sourceCodeStart":5035,"sourceCodeEnd":5071,"githubUrl":"https://github.com/pola-rs/polars/blob/fe841f959ef4d2ceefc05a310d33ed7b1ab24e5e/py-polars/src/polars/lazyframe/frame.py#L5035-L5071","documentation":"LazyFrame.group_by() only accepts Polars expressions or objects directly convertible to one (column names as strings, lists of them). This error is thrown when an unconvertible object (e.g. a list literal, dict, Series misuse, or Python value) is passed to `by`. The hint suggests the common mistake of wrapping the column name in a keyword call, e.g. group_by(by='a') instead of group_by('a').","triggerScenarios":"Calling df.lazy().group_by(by=<non-expression>) where `by` is not a str, pl.Expr, or list of those — e.g. passing a Python list value, a dict, a Series used as `by=<series>` in keyword position, or writing group_by(by='col') with a string in the `by` keyword where parse_into_list_of_expressions rejects it.","commonSituations":"Migrating from pandas groupby where a list/Series is passed; writing group_by(by=['a','b']) after seeing the signature has a `by` parameter; confusing positional/named argument usage; passing a pandas Series or numpy array directly.","solutions":["Pass column names as positional strings or a list of strings: group_by('a') or group_by(['a','b'])","Use pl.col('a') expressions instead of raw Python objects","If you used the `by=` keyword with a string/list of strings, drop the keyword and pass positionally","Convert foreign containers (pandas Series, numpy arrays) to Python lists or pl.Series first"],"exampleFix":"// before\ndf.lazy().group_by(by=['a', 'b']).agg(pl.col('x').sum())\n// after\ndf.lazy().group_by(['a', 'b']).agg(pl.col('x').sum())","handlingStrategy":"type-guard","validationCode":"def valid_group_keys(by):\n    if isinstance(by, str):\n        return True\n    if isinstance(by, list):\n        return all(isinstance(x, (str, pl.Expr)) for x in by)\n    return isinstance(by, pl.Expr)\n# call: lf.group_by(by) only if valid_group_keys(by)","typeGuard":"def is_polars_key(v) -> bool:\n    return isinstance(v, (str, pl.Expr)) or (isinstance(v, list) and all(isinstance(x, (str, pl.Expr)) for x in v))","tryCatchPattern":"try:\n    out = lf.group_by(keys).agg(...)\nexcept TypeError as e:\n    if 'Expected Polars expression' in str(e):\n        keys = keys if isinstance(keys, list) else [keys]\n        keys = [k if isinstance(k, (str, pl.Expr)) else str(k) for k in keys]\n        out = lf.group_by(keys).agg(...)","preventionTips":["Pass group keys positionally as strings or pl.col expressions","Never wrap the column name in by= keyword form","Convert pandas Series/numpy arrays to Python lists before grouping","Add a unit test covering each dynamic key source"],"tags":["polars","python","type-mismatch","groupby"],"backgroundTag":"invalid-argument-value","analyzedSha":"fe841f959ef4d2ceefc05a310d33ed7b1ab24e5e","analyzedAt":"2026-09-18T22:14:11.667Z","contentChangedAt":"2026-09-18T22:14:11.667Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}