pola-rs/polars · error · TypeError
passing Expr objects to the DataFrame constructor is not…
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
Raised by _expand_dict_values when a dict passed to the DataFrame constructor contains pl.Expr values. Expressions are lazy and unevaluated, so they cannot become column data; Polars raises TypeError with a hint to evaluate the expression first or to explicitly wrap it in a list for an Object column.
Solutions
- Evaluate the expression first, e.g. df.select(expr) and then build the DataFrame from the result
- Convert the underlying data to a Series/list before constructing
- If an Object column of expressions is truly intended, pass a list: {'a': [pl.col('x')]}
Example fix
// before
df = pl.DataFrame({'double_x': pl.col('x') * 2})
// after
df = df.select((pl.col('x') * 2).alias('double_x')) Defensive patterns
Strategy: type-guard
Validate before calling
if isinstance(data, dict):
exprs = [v for v in data.values() if isinstance(v, pl.Expr)]
assert not exprs, f'Expr values cannot be column data: {exprs}' Type guard
def is_expr_dict(data: dict) -> bool:
return any(isinstance(v, pl.Expr) for v in data.values()) Try / catch
try:
df = pl.DataFrame(data)
except TypeError as e:
if 'passing Expr objects' in str(e):
raise TypeError('evaluate expressions with select/with_columns first') from e
raise Prevention
- Only build DataFrames from evaluated data (lists, Series, arrays)
- Use df.select/with_columns for expression logic
- Watch for accidental Expr leakage when generating column specs dynamically
When it happens
Trigger: pl.DataFrame({'a': pl.col('x') * 2}) — passing an Expr directly as a dict value to pl.DataFrame.__init__ or dict_to_pydf.
Common situations: Confusing the expression context (df.select / with_columns) with the constructor, translating pandas code where such a value would have been a Series, building column definitions dynamically and accidentally using expressions.
Related errors
- accessing ` ` from the top-level `polars` module was…
- altair>=5.4.0 is required for `.plot`
- `arctan2` expected a `str` or `Expr` got a
- `arctan2` expected a `str` or `Expr` got a
- arr.dot query vector must be one-dimensional
AI-assisted analysis of pola-rs/polars@fe841f959e (2026-09-18).
Data as JSON: /api/errors/ffc75539ce5dd2ae.
Report an issue: GitHub.
Appendix: 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 fe841f959e)