pola-rs/polars · error
passing Expr objects to the DataFrame constructor is not sup
Error message
passing Expr objects to the DataFrame constructor is not supported Hint: Try evaluating the expression first using `select`, or if you meant to create an Object column containing expressions, pass a list of Expr objects instead.
What it means
When expanding dict data for DataFrame construction, polars refuses values that are polars Expressions: an Expr is a lazy, context-dependent object with no data to place in a column, so the constructor cannot materialize it. The error tells you to evaluate the expression in a frame context (select/with_columns) or, if an Object column of expressions is genuinely intended, to wrap the Exprs in a list.
Source
Thrown at py-polars/src/polars/_utils/construction/dataframe.py:355
def _expand_dict_values(
data: Mapping[str, ArrayLike | NonNestedLiteral | None],
*,
schema_overrides: SchemaDict | None = None,
strict: bool = True,
order: Sequence[str] | None = None,
nan_to_null: bool = False,
) -> dict[str, Series]:
"""Expand any scalar values in dict data (propagate literal as array)."""
updated_data = {}
if data:
if any(isinstance(val, pl.Expr) for val in data.values()):
msg = (
"passing Expr objects to the DataFrame constructor is not supported"
"\n\nHint: Try evaluating the expression first using `select`,"
" or if you meant to create an Object column containing expressions,"
" pass a list of Expr objects instead."
)
raise TypeError(msg)
dtypes = schema_overrides or {}
data = _expand_dict_data(data, dtypes, strict=strict)
array_len = max((arrlen(val) or 0) for val in data.values())
if array_len > 0:
for name, val in data.items():
dtype = dtypes.get(name)
if isinstance(val, dict) and dtype != Struct:
vdf = pl.DataFrame(val, strict=strict)
if (
vdf.height == 1
and array_len > 1
and all(not d.is_nested() for d in vdf.schema.values())
):
s_vals = {
nm: vdf[nm].extend_constant(v, n=(array_len - 1))
for nm, v in val.items()
}View on GitHub (pinned to df599052da)
Solutions
- Evaluate against an existing frame: `df.select((pl.col("a") + 1).alias("x"))` or `df.with_columns(...)`
- For constants use plain Python scalars or lists: `pl.DataFrame({"x": [3]})`
- If you truly want an Object column storing Expr objects (meta-programming/tests), wrap in a list: `pl.DataFrame({"e": [pl.col("a")]})`
Example fix
# before
pl.DataFrame({"x": pl.col("a") * 2})
# TypeError: passing Expr objects to the DataFrame constructor is not supported
# after — evaluate in a frame context
df.select((pl.col("a") * 2).alias("x"))
# after — constant column
pl.DataFrame({"x": [3]})
# after — deliberate Object column of Exprs
pl.DataFrame({"exprs": [pl.col("a") * 2]}) Defensive patterns
Strategy: type-guard
Validate before calling
import polars as pl
def dict_is_constructible(data: dict) -> bool:
return not any(isinstance(v, pl.Expr) for v in data.values())
assert dict_is_constructible({"x": pl.col("a")}) is False Type guard
import polars as pl
def contains_expr(data: dict) -> bool:
"""True if any dict value is a polars Expr (which the constructor rejects)."""
return any(isinstance(v, pl.Expr) for v in data.values()) Try / catch
try:
df = pl.DataFrame(data)
except TypeError as e:
if "Expr objects" not in str(e):
raise
df = base_df.select([v.alias(k) for k, v in data.items()]) # evaluate in frame context Prevention
- Use pl.lit/pl.col only inside select/with_columns/lazy contexts, never as constructor values
- Pass plain Python scalars/lists for constant columns
- Wrap expressions in a list only when you deliberately want an Object column of Exprs
When it happens
Trigger: `pl.DataFrame({"x": pl.col("a") + 1})` or `pl.DataFrame({"x": pl.lit(3)})` — any dict value that is a `pl.Expr` instance. Typical when porting pandas-style code where scalar/vector expressions were passed to the constructor.
Common situations: Porting `pd.DataFrame({"x": df["a"] + 1})` habits to polars; building fixtures dynamically; assuming pl.lit works as an inline constant in constructors (use plain Python scalars instead).
Related errors
- the given column-schema names do not match the data dictiona
- data does not match the number of columns
- dimensions of columns arg ({len(columns)}) must match data d
- `orient` must be one of {'col', 'row', None}, got {orient!r}
- Pandas dataframe contains non-unique indices and/or column n
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/ffc75539ce5dd2ae.
Report an issue: GitHub.