pola-rs/polars · error · ShapeError
data does not match the number of columns
Error message
data does not match the number of columns
What it means
While unpacking a `schema` argument for DataFrame construction, polars derives column names and compares their count against n_expected — the number of columns the data actually provides. A mismatch raises ShapeError (from polars.exceptions), covering sequence/list-style schemas where the number of names disagrees with the data's column count.
Source
Thrown at py-polars/src/polars/_utils/construction/dataframe.py:226
return columns, schema_overrides
# determine column names from schema
if isinstance(schema, Mapping):
column_names: list[str] = list(schema)
schema = list(schema.items())
else:
column_names = []
for i, col in enumerate(schema):
if isinstance(col, str):
unnamed = not col and col not in schema_overrides
col = f"column_{i}" if unnamed else col
else:
col = col[0]
column_names.append(col)
if n_expected is not None and len(column_names) != n_expected:
msg = "data does not match the number of columns"
raise ShapeError(msg)
# determine column dtypes from schema and lookup_names
lookup: dict[str, str] | None = (
{
col: name
for col, name in zip_longest(column_names, lookup_names)
if name is not None
}
if lookup_names
else None
)
column_dtypes: dict[str, PolarsDataType] = {}
for col in schema:
if isinstance(col, str):
continue
name, dtype = colView on GitHub (pinned to df599052da)
Solutions
- Make the lengths agree — one name per data column
- Omit the schema and rename afterwards: `df.rename({"old": "new"})` or `df.columns = [...]`
- Generate names programmatically: `schema=[f"column_{i}" for i in range(n_cols)]`
- Catch `polars.exceptions.ShapeError` at the boundary to re-raise an app-level message with the data's actual width
Example fix
# before pl.DataFrame([[1, 2], [3, 4]], schema=["a"]) # ShapeError: data does not match the number of columns # after pl.DataFrame([[1, 2], [3, 4]], schema=["a", "b"])
Defensive patterns
Strategy: validation
Validate before calling
import polars as pl
def width(rows: list[list]) -> int:
return len(rows[0]) if rows else 0
names = ["a", "b"]
rows = [[1, 2], [3, 4]]
assert len(names) == width(rows), f"schema has {len(names)} names but data has {width(rows)} columns"
df = pl.DataFrame(rows, schema=names, orient="row") Type guard
def schema_matches_width(schema: list[str] | None, n_cols: int) -> bool:
"""True if schema length equals the data's column count (or schema is None)."""
return schema is None or len(schema) == n_cols Try / catch
from polars.exceptions import ShapeError
try:
df = pl.DataFrame(rows, schema=names)
except ShapeError as e:
raise ValueError(f"input width changed: expected {len(names)} columns, got {len(rows[0]) if rows else 0}") from e Prevention
- Derive column counts from the data instead of hardcoding name lists
- Validate incoming rows for consistent width before construction (polars also errors on ragged rows)
- Catch polars.exceptions.ShapeError at data-ingestion boundaries to surface app-level diagnostics
When it happens
Trigger: `pl.DataFrame([[1, 2], [3, 4]], schema=["a"])` (2 data columns, 1 schema name), or `pl.DataFrame(data_with_3_columns, schema=["a", "b"])` — any positional schema whose length differs from the number of columns in the data.
Common situations: Hardcoded name lists not updated after upstream added/removed a field; ragged row data producing an unexpected column count; schemas written for one dataset reused on another with a different width.
Related errors
- dimensions of columns arg ({len(columns)}) must match data d
- the given column-schema names do not match the data dictiona
- matrix columns should be equal to list used to determine col
- passing Expr objects to the DataFrame constructor is not sup
- `orient` must be one of {'col', 'row', None}, got {orient!r}
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/da82a22e0f65b44d.
Report an issue: GitHub.