pola-rs/polars · error · ValueError

LazyFrame `how` must be one of {{{allowed}}}, got {how!r}

Error message

LazyFrame `how` must be one of {{{allowed}}}, got {how!r}

What it means

The LazyFrame branch of pl.concat supports vertical, vertical_relaxed, diagonal, diagonal_relaxed, horizontal, and horizontal_extend (plus align strategies handled earlier); any other how value raises this ValueError listing the valid ConcatMethod values. The neighboring rule for Series sequences is even stricter: only 'vertical' is supported.

Source

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

            return wrap_ldf(
                plr.concat_lf_horizontal(
                    elems,
                    parallel=parallel,
                    strict=True,
                )
            )
        elif how == "horizontal_extend":
            return wrap_ldf(
                plr.concat_lf_horizontal(
                    elems,
                    parallel=parallel,
                    strict=False,
                )
            )
        else:
            allowed = ", ".join(repr(m) for m in get_args(ConcatMethod))
            msg = f"LazyFrame `how` must be one of {{{allowed}}}, got {how!r}"
            raise ValueError(msg)

    elif is_non_empty_sequence_of(elems, pl.Series):
        if how == "vertical":
            out = wrap_s(plr.concat_series(elems))
        else:
            msg = "Series only supports 'vertical' concat strategy"
            raise ValueError(msg)

    elif is_non_empty_sequence_of(elems, pl.Expr):
        return wrap_expr(plr.concat_expr([e._pyexpr for e in elems], rechunk))
    else:
        msg = f"did not expect type: {qualified_type_name(elems[0])!r} in `concat`"
        raise TypeError(msg)

    if rechunk:
        return out.rechunk()
    return out

View on GitHub (pinned to df599052da)

Solutions

  1. Use an allowed value exactly; the error message enumerates them
  2. Validate dynamic values against typing.get_args(polars._typing.ConcatMethod) before the call
  3. Confirm you are in the intended branch: collect()/lazy() the inputs if you meant to target a different frame type

Example fix

# before
pl.concat([lf1, lf2], how='horizontal-relaxed')

# after
pl.concat([lf1, lf2], how='vertical_relaxed')

# validating a dynamic value:
from typing import get_args
from polars._typing import ConcatMethod
if how not in get_args(ConcatMethod):
    raise ValueError(f'unsupported how: {how!r}')
Defensive patterns

Strategy: validation

Validate before calling

from typing import get_args
from polars._typing import ConcatMethod

how = (how or 'vertical').strip()
if how not in get_args(ConcatMethod):
    raise ValueError(f'unsupported concat how: {how!r}; allowed: {get_args(ConcatMethod)}')
out = pl.concat(lazy_frames, how=how)

Type guard

from typing import get_args
from polars._typing import ConcatMethod

def is_concat_method(x: object) -> bool:
    return isinstance(x, str) and x in get_args(ConcatMethod)

Prevention

When it happens

Trigger: pl.concat([lf1, lf2], how='horizonta') (typo); a strategy name valid for a different overload; how sourced from config or a function parameter and never validated; strategies removed or renamed across Polars versions.

Common situations: Dynamic how selection in data pipelines; wrapper libraries exposing a passthrough strategy parameter; version upgrades where supported strategy sets shifted.

Related errors


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