{"record":{"id":"f0b179b3d822a79d","repo":"pola-rs/polars","slug":"must-specify-either-a-fill-value-or-strategy","errorCode":null,"errorMessage":"must specify either a fill `value` or `strategy`","messagePattern":"must specify either a fill `value` or `strategy`","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/expr/expr.py","lineNumber":3348,"sourceCode":"        └──────┴─────┘\n        >>> df.with_columns(pl.all().fill_null(pl.all().median()))\n        shape: (3, 2)\n        ┌─────┬─────┐\n        │ a   ┆ b   │\n        │ --- ┆ --- │\n        │ f64 ┆ f64 │\n        ╞═════╪═════╡\n        │ 1.0 ┆ 4.0 │\n        │ 2.0 ┆ 5.0 │\n        │ 1.5 ┆ 6.0 │\n        └─────┴─────┘\n        \"\"\"\n        if value is not None and strategy is not None:\n            msg = \"cannot specify both `value` and `strategy`\"\n            raise ValueError(msg)\n        elif value is None and strategy is None:\n            msg = \"must specify either a fill `value` or `strategy`\"\n            raise ValueError(msg)\n        elif strategy not in (\"forward\", \"backward\") and limit is not None:\n            msg = \"can only specify `limit` when strategy is set to 'backward' or 'forward'\"\n            raise ValueError(msg)\n\n        if value is not None:\n            value_pyexpr = parse_into_expression(value, str_as_lit=True)\n            return wrap_expr(self._pyexpr.fill_null(value_pyexpr))\n        else:\n            assert strategy is not None\n            return wrap_expr(self._pyexpr.fill_null_with_strategy(strategy, limit))\n\n    def fill_nan(self, value: int | float | Expr | None) -> Expr:\n        \"\"\"\n        Fill floating point NaN value with a fill value.\n\n        .. engine-support:: in-memory, streaming\n\n        Parameters","sourceCodeStart":3330,"sourceCodeEnd":3366,"githubUrl":"https://github.com/pola-rs/polars/blob/df599052daf96e7a9cc30a3b0c6bd25d6947e3c0/py-polars/src/polars/expr/expr.py#L3330-L3366","documentation":"Raised by Expr.fill_null when neither a fill `value` nor a fill `strategy` is given. Polars requires exactly one of the two so the operation is well-defined; an empty fill_null() call is almost always a plumbing bug (a value that resolved to None) rather than a meaningful no-op. Like its sibling checks, it raises at expression-construction time.","triggerScenarios":"pl.col('a').fill_null() with no arguments, or fill_null(value=None, strategy=None) when the value comes from a variable that is unexpectedly None.","commonSituations":"Config-driven pipelines where the fill value is optional and was never set; helper functions that forward **kwargs to fill_null and received neither; copy-paste stubs left with an empty call.","solutions":["Pass an explicit fill value, e.g. fill_null(0).","Or pass a strategy, e.g. fill_null(strategy='mean').","If the value is optional by design, branch your code: skip the fill entirely when no value is configured."],"exampleFix":"# before\nfill = None\npl.col('a').fill_null(fill)\n\n# after\nfill = None\nexpr = pl.col('a').fill_null(fill) if fill is not None else pl.col('a')","handlingStrategy":"validation","validationCode":"value = None  # from config\nassert value is not None or strategy is not None, 'fill_null needs a value or a strategy'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never call fill_null with dynamically-empty arguments; branch instead.","Validate optional config before building polars expressions.","Remember None is a valid sentinel here, so an accidental None looks like 'not specified'."],"tags":["validation","null-handling","polars","expression"],"backgroundTag":null,"analyzedSha":"df599052daf96e7a9cc30a3b0c6bd25d6947e3c0","analyzedAt":"2026-08-16T12:10:03.978Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}