pola-rs/polars · error · ValueError

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

Error message

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

What it means

For a sequence of DataFrames, pl.concat supports a fixed set of strategies — vertical, vertical_relaxed, diagonal, diagonal_relaxed, horizontal, horizontal_extend, plus the align family handled earlier in the function. Any other how value falls through to this ValueError, whose message enumerates the allowed ConcatMethod values.

Source

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

            out = wrap_df(plr.concat_df_diagonal(elems))
        elif how == "diagonal_relaxed":
            out = wrap_ldf(
                plr.concat_lf_diagonal(
                    [df.lazy() for df in elems],
                    rechunk=rechunk,
                    parallel=parallel,
                    to_supertypes=True,
                    maintain_order=True,
                )
            )._collect_eager(optimizations=QueryOptFlags._eager())
        elif how == "horizontal":
            out = wrap_df(plr.concat_df_horizontal(elems, strict=True))
        elif how == "horizontal_extend":
            out = wrap_df(plr.concat_df_horizontal(elems, strict=False))
        else:
            allowed = ", ".join(repr(m) for m in get_args(ConcatMethod))
            msg = f"DataFrame `how` must be one of {{{allowed}}}, got {how!r}"
            raise ValueError(msg)

    elif is_non_empty_sequence_of(elems, pl.LazyFrame):
        how = _normalize_horizontal_concat("concat", how, strict=strict)

        if how in ("vertical", "vertical_relaxed"):
            return wrap_ldf(
                plr.concat_lf(
                    elems,
                    rechunk=rechunk,
                    parallel=parallel,
                    to_supertypes=how.endswith("relaxed"),
                    maintain_order=True,
                )
            )
        elif how in ("diagonal", "diagonal_relaxed"):
            return wrap_ldf(
                plr.concat_lf_diagonal(
                    elems,

View on GitHub (pinned to df599052da)

Solutions

  1. Use one of the allowed values exactly; the error message lists them
  2. Validate config-supplied values before calling: check membership in typing.get_args(polars._typing.ConcatMethod)
  3. Double-check the docs for the input type you are actually passing — supported strategies differ between DataFrame, LazyFrame, and Series

Example fix

# before
pl.concat(dfs, how='verticle')

# after
pl.concat(dfs, how='vertical')

# validating a dynamic value:
from typing import get_args
from polars._typing import ConcatMethod
assert how in get_args(ConcatMethod), f'bad 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(dfs, 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: Typos like 'verticle' or 'vertical-relaxed'; how='cross' (not a concat strategy); a how value read from config/env/CLI that was never validated; a strategy that exists only for another input type.

Common situations: Config-driven concat strategies; version drift where strategy names changed or were added; copy-paste from docs of a different overload (LazyFrame vs DataFrame vs Series); user-supplied parameters in library wrappers.

Related errors


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