pola-rs/polars · error

dimensions of `schema` ({n_schema_cols}) must match data dim

Error message

dimensions of `schema` ({n_schema_cols}) must match data dimensions ({n_columns})

What it means

In the NumPy construction path, when a schema is supplied its length must equal the column count implied by the array shape and orient (shape[1] for row/None on 2D, shape[0] for col on 2D). The only exception is len(schema) == 1, which squeezes everything into a single named column; any other mismatch raises this ValueError.

Source

Thrown at py-polars/src/polars/_utils/construction/dataframe.py:1283

            elif orient == "row":
                n_columns = shape[1]
            elif orient == "col":
                n_columns = shape[0]
            else:
                msg = f"`orient` must be one of {{'col', 'row', None}}, got {orient!r}"
                raise ValueError(msg)
        else:
            if shape == ():
                msg = "cannot create DataFrame from zero-dimensional array"
            else:
                msg = f"cannot create DataFrame from array with more than two dimensions; shape = {shape}"
            raise ValueError(msg)

    if schema is not None and len(schema) != n_columns:
        if (n_schema_cols := len(schema)) != 1:
            msg = f"dimensions of `schema` ({n_schema_cols}) must match data dimensions ({n_columns})"
            raise ValueError(msg)
        n_columns = n_schema_cols

    column_names, schema_overrides = _unpack_schema(
        schema, schema_overrides=schema_overrides, n_expected=n_columns
    )

    # Convert data to series
    if structured_array:
        data_series = [
            pl.Series(
                name=series_name,
                values=data[record_name],
                dtype=schema_overrides.get(record_name),
                strict=strict,
                nan_to_null=nan_to_null,
            )._s
            for series_name, record_name in zip(column_names, record_names, strict=True)
        ]

View on GitHub (pinned to df599052da)

Solutions

  1. Compute the expected width from the shape and orient, then pass exactly that many names.
  2. Omit schema, let polars infer, and rename afterwards: df.columns = [...].
  3. For a 1D array you want named, pass exactly one name (the allowed len==1 squeeze) or reshape to (n, 1) first.

Example fix

// before
arr = np.zeros((3, 2))
df = pl.DataFrame(arr, schema=["a", "b", "c"])

// after
df = pl.DataFrame(arr, schema=["a", "b"])
// or: df = pl.DataFrame(arr).rename({"column_0": "a", "column_1": "b"})
Defensive patterns

Strategy: validation

Validate before calling

arr = np.asarray(value)
n_cols = arr.shape[1] if (arr.ndim == 2 and orient in (None, "row")) else (arr.shape[0] if orient == "col" else 1)
if schema is not None and len(schema) != n_cols and len(schema) != 1:
    raise ValueError(f"len(schema)={len(schema)} but array provides {n_cols} columns")
df = pl.DataFrame(arr, schema=schema, orient=orient)

Try / catch

try:
    df = pl.DataFrame(arr, schema=schema, orient=orient)
except ValueError as e:
    if "must match data dimensions" in str(e):
        df = pl.DataFrame(arr)  # infer names, rename afterwards
        df.columns = list(schema)
    else:
        raise

Prevention

When it happens

Trigger: pl.DataFrame(np.zeros((3, 2)), schema=["a", "b", "c"]); pl.DataFrame(np.arange(5), schema=["a", "b"]); switching orient from "col" to "row" on a non-square array without updating the schema length.

Common situations: Array was transposed upstream so row/column counts swapped; hardcoded name lists drifting out of sync with generated data; 1D data assumed to be 2D.

Related errors


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