{"record":{"id":"b8394ffd9d69e073","repo":"pola-rs/polars","slug":"length-must-be-an-integer-string-or-expression","errorCode":null,"errorMessage":"'length' must be an integer, string, or expression, not {type(length).__name__}","messagePattern":"'length' must be an integer, string, or expression, not (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/expr/list.py","lineNumber":1139,"sourceCode":"        ┌─────────────┬───────────┐\n        │ a           ┆ slice     │\n        │ ---         ┆ ---       │\n        │ list[i64]   ┆ list[i64] │\n        ╞═════════════╪═══════════╡\n        │ [1, 2, … 4] ┆ [2, 3]    │\n        │ [10, 2, 1]  ┆ [2, 1]    │\n        └─────────────┴───────────┘\n        \"\"\"\n        if isinstance(offset, Collection) and not isinstance(offset, str):\n            msg = f\"'offset' must be an integer, string, or expression, not {type(offset).__name__}\"\n            raise TypeError(msg)\n        if (\n            length is not None\n            and isinstance(length, Collection)\n            and not isinstance(length, str)\n        ):\n            msg = f\"'length' must be an integer, string, or expression, not {type(length).__name__}\"\n            raise TypeError(msg)\n\n        offset_pyexpr = parse_into_expression(offset)\n        length_pyexpr = parse_into_expression(length)\n        return wrap_expr(self._pyexpr.list_slice(offset_pyexpr, length_pyexpr))\n\n    def head(self, n: int | str | Expr = 5) -> Expr:\n        \"\"\"\n        Slice the first `n` values of every sub-list.\n\n        .. engine-support:: in-memory, streaming, distributed\n\n        Parameters\n        ----------\n        n\n            Number of values to return for each sublist.\n\n        Examples\n        --------","sourceCodeStart":1121,"sourceCodeEnd":1157,"githubUrl":"https://github.com/pola-rs/polars/blob/df599052daf96e7a9cc30a3b0c6bd25d6947e3c0/py-polars/src/polars/expr/list.py#L1121-L1157","documentation":"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'.","triggerScenarios":"pl.col('l').list.slice(1, [2, 1]) — passing per-row lengths as a Python list; wrappers accepting Sequence[int] for lengths.","commonSituations":"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.","solutions":["Constant length: list.slice(1, 2).","Per-row lengths: list.slice(1, pl.col('lens')) after adding them as a column.","Fix defaults: use None, not [], for 'unspecified'."],"exampleFix":"# before\npl.col('l').list.slice(1, length=[2, 1])\n\n# after\npl.col('l').list.slice(1, 2)\n# per-row:\ndf.with_columns(pl.col('l').list.slice(pl.col('offs'), pl.col('lens')))","handlingStrategy":"type-guard","validationCode":"from collections.abc import Collection\nif length is not None and isinstance(length, Collection) and not isinstance(length, str):\n    raise TypeError(f'length must be int/str/Expr, got {type(length).__name__}')","typeGuard":"from collections.abc import Collection\n\ndef is_valid_length(v) -> bool:\n    return v is None or isinstance(v, (int, str)) or hasattr(v, '_pyexpr')","tryCatchPattern":null,"preventionTips":["Same rule as offset: int, str, or Expr only.","Default optional expression args to None, never to [] or ()."],"tags":["type-guard","polars","expression","list","slice"],"backgroundTag":null,"analyzedSha":"df599052daf96e7a9cc30a3b0c6bd25d6947e3c0","analyzedAt":"2026-08-16T12:10:03.978Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}