pola-rs/polars · error · TypeError
did not expect type: {qualified_type_name(elems[0])!r} in `c
Error message
did not expect type: {qualified_type_name(elems[0])!r} in `concat` What it means
Raised by pl.concat when the input list is not a homogeneous sequence of DataFrame, LazyFrame, Series, or Expr. The dispatcher tests each type in turn (is_non_empty_sequence_of); when all fail it raises TypeError naming the qualified type of elems[0], e.g. 'builtins.str', 'numpy.ndarray', 'NoneType'.
Source
Thrown at py-polars/src/polars/functions/eager.py:375
)
)
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
def union(
items: Iterable[PolarsType],
*,
how: ConcatMethod = "vertical",
strict: bool | None = None,
) -> PolarsType:
"""
Combine multiple DataFrames, LazyFrames, or Series into a single object.
.. warning::
This function does not guarantee any specific ordering of rows in the result.
If you need predictable row ordering, use `pl.concat()` instead.View on GitHub (pinned to df599052da)
Solutions
- Make all elements the same type: collect LazyFrames (lf.collect()) or make DataFrames lazy (df.lazy())
- Wrap mapping values: pl.concat(list(frames_by_name.values()))
- Materialize generators with list() first so type dispatch inspects real items and mixed types become visible
Example fix
# before pl.concat([df1, lf2]) # TypeError pl.concat(frames_by_name) # dict -> TypeError # after pl.concat([df1, lf2.collect()]) pl.concat(list(frames_by_name.values()))
Defensive patterns
Strategy: type-guard
Type guard
def is_concatable(items) -> bool:
items = list(items)
if not items:
return False
first = type(items[0])
return first in (pl.DataFrame, pl.LazyFrame, pl.Series, pl.Expr) and all(
type(e) is first for e in items
) Prevention
- Annotate helper params as list[pl.DataFrame] and convert once at the boundary
- Always call list() on generators before pl.concat so mixed types surface early
- Pass dict values, never the dict itself
When it happens
Trigger: pl.concat([df, lf]) mixing DataFrame and LazyFrame; pl.concat(['a', 'b']); passing a dict or dict.keys() instead of its values; a numpy array or list-of-lists; a generator that yields non-frame objects.
Common situations: Passing a dict of frames instead of list(d.values()); mixing eager frames (read_parquet) with lazy ones (scan_parquet) from different pipeline stages; forgetting list() around a generator whose content is unknown; passing raw Python containers where frames were expected.
Related errors
- `strict` cannot be used with `how='horizontal_extend'`
- cannot concat empty list
- {how!r} strategy is not supported for {qualified_type_name(e
- {how!r} strategy requires at least one common column
- DataFrame `how` must be one of {{{allowed}}}, got {how!r}
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/1499754eebe1501a.
Report an issue: GitHub.