{"record":{"id":"c8085e9b11d550cf","repo":"pola-rs/polars","slug":"cannot-specify-both-value-and-strategy","errorCode":null,"errorMessage":"cannot specify both `value` and `strategy`","messagePattern":"cannot specify both `value` and `strategy`","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/expr/expr.py","lineNumber":3345,"sourceCode":"        │ 1    ┆ 4.0 │\n        │ 2    ┆ 5.0 │\n        │ null ┆ 6.0 │\n        └──────┴─────┘\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","sourceCodeStart":3327,"sourceCodeEnd":3363,"githubUrl":"https://github.com/pola-rs/polars/blob/df599052daf96e7a9cc30a3b0c6bd25d6947e3c0/py-polars/src/polars/expr/expr.py#L3327-L3363","documentation":"Raised by Expr.fill_null when both a fill `value` and a fill `strategy` are passed. Polars validates arguments in the Python layer before dispatching to the Rust engine: filling is either an explicit literal/expression value or a strategy ('forward', 'backward', 'mean', 'median', 'min', 'max', 'zero', 'one'), never both, because the result would be ambiguous. The check happens eagerly at expression-construction time, before any data is touched.","triggerScenarios":"Calls like pl.col('a').fill_null(0, strategy='forward') or df.fill_null(value=0, strategy='mean'). It fires at expression build time, even inside lazy queries that never run.","commonSituations":"Refactoring old code that used strategy= and adding a value= default; copy-pasting snippets that merge both styles; config-driven pipelines where a fallback value and a fallback strategy are both populated from settings.","solutions":["Remove one of the two arguments: keep `value` for an explicit fill, keep `strategy` for a computed fill.","If you wanted 'fill with X where possible, else forward-fill', express it explicitly: pl.col('a').fill_null(0) or use coalesce of two fills.","Audit the call site for kwargs built dynamically (e.g. **fill_kwargs) and make sure only one key survives."],"exampleFix":"# before\npl.col('a').fill_null(0, strategy='forward')\n\n# after\npl.col('a').fill_null(0)\n# or\npl.col('a').fill_null(strategy='forward')","handlingStrategy":"validation","validationCode":"def check_fill_args(value, strategy, limit=None):\n    if value is not None and strategy is not None:\n        raise ValueError('pass only one of value / strategy')\n    if value is None and strategy is None:\n        raise ValueError('pass at least one of value / strategy')\n    if limit is not None and strategy not in ('forward', 'backward'):\n        raise ValueError('limit requires strategy forward/backward')\n\ncheck_fill_args(0, 'forward')  # fails fast before polars sees it","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat fill_null kwargs as mutually exclusive when building dynamic argument dicts.","Prefer explicit value fills for constants and strategy fills for interpolation; do not combine.","Fail fast in your own wrapper so the error names your config, not polars internals."],"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"}