{"record":{"id":"35c6275863dc5535","repo":"pola-rs/polars","slug":"map-with-returns-scalar-false-must-return-a-se","errorCode":null,"errorMessage":"`map` with `returns_scalar=False` must return a Series; found {qualified_type_name(rv)!r}.\n\nIf `returns_scalar` is set to `True`, a returned value can be a scalar value.","messagePattern":"`map` with `returns_scalar=False` must return a Series; found (.+?)\\.\n\nIf `returns_scalar` is set to `True`, a returned value can be a scalar value\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/functions/lazy.py","lineNumber":1088,"sourceCode":"        try:\n            rv = self.function(slp, *args, **kwargs)\n        except TypeError as e:\n            if \"unexpected keyword argument 'return_dtype'\" in e.args[0]:\n                kwargs.pop(\"return_dtype\")\n                rv = self.function(slp, *args, **kwargs)\n            else:\n                raise\n\n        if _check_for_numpy(rv) and isinstance(rv, np.ndarray):\n            rv = pl.Series(rv, dtype=return_dtype)\n\n        if isinstance(rv, pl.Series):\n            return rv._s\n        elif self.returns_scalar:\n            return pl.Series([rv], dtype=return_dtype)._s\n        else:\n            msg = f\"`map` with `returns_scalar=False` must return a Series; found {qualified_type_name(rv)!r}.\\n\\nIf `returns_scalar` is set to `True`, a returned value can be a scalar value.\"\n            raise TypeError(msg)\n\n\ndef map_batches(\n    exprs: Sequence[str | Expr],\n    function: Callable[[Sequence[Series]], Series | Any],\n    return_dtype: PolarsDataType | pl.DataTypeExpr | None = None,\n    *,\n    is_elementwise: bool = False,\n    returns_scalar: bool = False,\n) -> Expr:\n    \"\"\"\n    Map a custom function over multiple columns/expressions.\n\n    Produces a single Series result.\n\n    .. warning::\n        This method is much slower than the native expressions API.\n        Only use it if you cannot implement your logic otherwise.","sourceCodeStart":1070,"sourceCodeEnd":1106,"githubUrl":"https://github.com/pola-rs/polars/blob/fe841f959ef4d2ceefc05a310d33ed7b1ab24e5e/py-polars/src/polars/functions/lazy.py#L1070-L1106","documentation":"The Python function passed to `Expr.map` is applied per group/window and, with `returns_scalar=False` (the default), must return a `pl.Series`. If it returns any other object (list, scalar, numpy array), the map callback raises TypeError. Scalars require explicitly setting `returns_scalar=True`.","triggerScenarios":"`df.select(pl.col(\"x\").map(lambda s: s.sum()))` or a lambda returning `s.to_list()` / a plain value while `returns_scalar` is left False.","commonSituations":"Confusing `map` with `map_elements`; migrating from older `apply`; forgetting `returns_scalar=True` for aggregate-style callbacks; returning numpy arrays instead of Series.","solutions":["Return a `pl.Series` from the mapped function","Set `returns_scalar=True` if the function returns a single scalar value","Use `map_batches` if you want batch semantics with flexible return handling","Wrap non-Series results: `pl.Series(rv)`"],"exampleFix":"// before\npl.col(\"x\").map(lambda s: s.sum())\n// after\npl.col(\"x\").map(lambda s: s.sum(), returns_scalar=True)\n# or return a Series:\npl.col(\"x\").map(lambda s: pl.Series([s.sum()]))","handlingStrategy":"type-guard","validationCode":"def mapped(fn, returns_scalar=False):\n    def wrapped(s):\n        rv = fn(s)\n        if not returns_scalar and not isinstance(rv, pl.Series):\n            raise TypeError(\"map function must return pl.Series or set returns_scalar=True\")\n        return rv\n    return wrapped","typeGuard":"def map_result_ok(rv, returns_scalar): return isinstance(rv, pl.Series) or returns_scalar","tryCatchPattern":"try:\n    out = df.select(pl.col(\"x\").map(fn))\nexcept TypeError:\n    out = df.select(pl.col(\"x\").map(fn, returns_scalar=True))","preventionTips":["Return pl.Series from map callbacks by default","Set returns_scalar=True for aggregating callbacks","Prefer map_batches for batch-style transforms"],"tags":["python","polars","map","type-mismatch"],"backgroundTag":"type-mismatch","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"}