pola-rs/polars · error · ValueError

expected at least one Series in 'coalesce' if 'eager=True'

Error message

expected at least one Series in 'coalesce' if 'eager=True'

What it means

Raised by polars.coalesce when eager=True yet none of the provided exprs is a pl.Series. The eager path builds a DataFrame from the Series inputs (using each Series' name) and runs the lazy coalesce on it, so it needs at least one materialized Series to anchor execution.

Source

Thrown at py-polars/src/polars/functions/lazy.py:2570

    │ null ┆ null ┆ null ┆ 10.0 │
    └──────┴──────┴──────┴──────┘

    >>> s1 = pl.Series("a", [None, 2, None])
    >>> s2 = pl.Series("b", [1, None, 3])
    >>> pl.coalesce(s1, s2, eager=True)
    shape: (3,)
    Series: 'a' [i64]
    [
        1
        2
        3
    ]
    """
    if eager:
        exprs = [exprs, *more_exprs]
        if not (series := [e for e in exprs if isinstance(e, pl.Series)]):
            msg = "expected at least one Series in 'coalesce' if 'eager=True'"
            raise ValueError(msg)

        exprs = [(e.name if isinstance(e, pl.Series) else e) for e in exprs]
        return pl.DataFrame(series).select(coalesce(exprs, eager=False)).to_series()
    else:
        exprs = parse_into_list_of_expressions(exprs, *more_exprs)
        return wrap_expr(plr.coalesce(exprs))


@overload
def from_epoch(column: str | Expr, time_unit: EpochTimeUnit = ...) -> Expr: ...


@overload
def from_epoch(
    column: Series | Sequence[int | float], time_unit: EpochTimeUnit = ...
) -> Series: ...

View on GitHub (pinned to df599052da)

Solutions

  1. Pass at least one Series, e.g. pl.coalesce(df['a'], df['b'], eager=True)
  2. Evaluate lazily instead: df.select(pl.coalesce(['a', 'b']))
  3. For filling nulls across columns in a DataFrame, use df.select(pl.coalesce(...)) or df.fill_nan/fill_null as appropriate

Example fix

// before
pl.coalesce([pl.col('a'), pl.col('b')], eager=True)
// after
pl.coalesce(df['a'], df['b'], eager=True)
# or:
df.select(pl.coalesce(['a', 'b']))
Defensive patterns

Strategy: validation

Validate before calling

import polars as pl

if eager and not any(isinstance(e, pl.Series) for e in ([exprs, *more_exprs] if not isinstance(exprs, (list, tuple)) else [*exprs, *more_exprs])):
    raise ValueError('coalesce(eager=True) needs at least one pl.Series')

Type guard

def has_at_least_one_series(exprs) -> bool:
    return any(isinstance(e, pl.Series) for e in exprs)

Try / catch

try:
    out = pl.coalesce(exprs, eager=True)
except ValueError:
    out = df.select(pl.coalesce(exprs)).to_series()

Prevention

When it happens

Trigger: pl.coalesce([pl.col('a'), pl.col('b')], eager=True); pl.coalesce('a', 'b', eager=True) with string column names; mixing only Exprs/strings with eager=True.

Common situations: Expecting eager=True to evaluate against 'the current DataFrame' (there is none in this API); upgrading scripts where coalesce was previously used only inside select; passing a list of column-name strings.

Related errors


AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16). Data as JSON: /api/errors/6b4638d1e8836565. Report an issue: GitHub.