pola-rs/polars · error · ValueError

cannot merge_sort empty list

Error message

cannot merge_sort empty list

What it means

Raised by pl.merge_sorted when `items` unpacks to zero elements. With nothing to merge there is no schema for the result, and returning an invented empty frame would hide bugs, so polars raises ValueError instead.

Source

Thrown at py-polars/src/polars/functions/eager.py:761

    │ megan  ┆ 33  │
    │ ida    ┆ 37  │
    │ steve  ┆ 42  │
    │ elise  ┆ 44  │
    └────────┴─────┘


    Notes
    -----
    Unless ``maintain_order=True``, no guarantee is given over the output
    row order when the key is equal between dataframes.

    The key(s) must be sorted in ascending order.
    """
    elems: Sequence[PolarsType] = list(items)

    if not elems:
        msg = "cannot merge_sort empty list"
        raise ValueError(msg)
    if len(elems) == 1 and isinstance(elems[0], (pl.DataFrame, pl.LazyFrame)):
        return elems[0]

    if not is_non_empty_sequence_of(
        elems, pl.DataFrame
    ) and not is_non_empty_sequence_of(  # type: ignore[redundant-expr]
        elems, pl.LazyFrame
    ):
        msg = f"merge_sorted is not supported for {qualified_type_name(elems[0])!r}"
        raise TypeError(msg)

    frames = [df.lazy() for df in elems]

    def reduce_fn(x: pl.LazyFrame, y: pl.LazyFrame) -> pl.LazyFrame:
        return x.merge_sorted(y, key=key, maintain_order=maintain_order)

    lf = reduce_balanced(reduce_fn, frames)
    eager = isinstance(elems[0], pl.DataFrame)

View on GitHub (pinned to df599052da)

Solutions

  1. Guard before the call and return a typed empty frame: pl.DataFrame(schema=schema) (plus .lazy() if the pipeline is lazy)
  2. Fix the upstream source so at least one frame is produced
  3. Treat 'no frames' as an explicit domain case in your pipeline rather than an error

Example fix

# before
out = pl.merge_sorted(frames, key='ts')  # frames == []

# after
schema = {'ts': pl.Datetime, 'v': pl.Float64}
out = pl.merge_sorted(frames, key='ts') if frames else pl.DataFrame(schema=schema).lazy()
Defensive patterns

Strategy: validation

Validate before calling

frames = list(items)
if not frames:
    out = pl.DataFrame(schema=expected_schema).lazy()
else:
    out = pl.merge_sorted(frames, key=key, maintain_order=maintain_order)

Prevention

When it happens

Trigger: pl.merge_sorted([], key='ts'); a comprehension of frames filtered to zero, e.g. [read(f) for f in paths if keep(f)] when nothing is kept; empty batch window in a streaming job.

Common situations: Scheduled jobs hitting an empty time window; glob that matched no files; conditional frame collection where no branch fired.

Related errors


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