{"record":{"id":"1464e40654630eec","repo":"pola-rs/polars","slug":"one-of-com-span-half-life-or-alpha-must","errorCode":null,"errorMessage":"one of `com`, `span`, `half_life`, or `alpha` must be set","messagePattern":"one of `com`, `span`, `half_life`, or `alpha` must be set","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/expr/expr.py","lineNumber":12814,"sourceCode":"            msg = f\"require `com` >= 0 (found {com!r})\"\n            raise ValueError(msg)\n        alpha = 1.0 / (1.0 + com)\n\n    elif span is not None:\n        if span < 1.0:\n            msg = f\"require `span` >= 1 (found {span!r})\"\n            raise ValueError(msg)\n        alpha = 2.0 / (span + 1.0)\n\n    elif half_life is not None:\n        if half_life <= 0.0:\n            msg = f\"require `half_life` > 0 (found {half_life!r})\"\n            raise ValueError(msg)\n        alpha = 1.0 - math.exp(-math.log(2.0) / half_life)\n\n    elif alpha is None:\n        msg = \"one of `com`, `span`, `half_life`, or `alpha` must be set\"\n        raise ValueError(msg)\n\n    elif not (0 < alpha <= 1):\n        msg = f\"require 0 < `alpha` <= 1 (found {alpha!r})\"\n        raise ValueError(msg)\n\n    return alpha\n\n\ndef _prepare_rolling_by_window_args(window_size: timedelta | str) -> str:\n    if isinstance(window_size, timedelta):\n        window_size = parse_as_duration_string(window_size)\n    return window_size\n","sourceCodeStart":12796,"sourceCodeEnd":12827,"githubUrl":"https://github.com/pola-rs/polars/blob/df599052daf96e7a9cc30a3b0c6bd25d6947e3c0/py-polars/src/polars/expr/expr.py#L12796-L12827","documentation":"_prepare_alpha's fallback branch fires when none of com, span, half_life, alpha is provided — every parameter defaults to None in ewm_mean, so a bare call has no decay specification at all. Since alpha cannot be inferred, polars raises ValueError rather than silently picking a default smoothing.","triggerScenarios":"pl.col('x').ewm_mean() with no arguments; or ewm_mean(com=None, ...) via a config dict where the decay key was never populated.","commonSituations":"Copy-pasted examples trimmed too aggressively; wrapper functions forwarding optional EWM params where none ended up set; refactors that moved the decay argument out and forgot to keep one.","solutions":["Add exactly one decay parameter, e.g. ewm_mean(span=10).","If a sensible default is wanted in your codebase, define it in your wrapper and always pass it.","Check that config parsing actually populates one of the four keys."],"exampleFix":"# before\npl.col('x').ewm_mean()\n\n# after\npl.col('x').ewm_mean(span=10)","handlingStrategy":"validation","validationCode":"provided = [p for p in (com, span, half_life, alpha) if p is not None]\nassert len(provided) == 1, f'need exactly one decay param, got {provided}'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["ewm_mean has no implicit default decay — always specify one.","Centralise the choice of span/com/half_life in one helper so call sites cannot forget it."],"tags":["validation","polars","expression","ewm","statistics"],"backgroundTag":null,"analyzedSha":"df599052daf96e7a9cc30a3b0c6bd25d6947e3c0","analyzedAt":"2026-08-16T12:10:03.978Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}