pola-rs/polars · error

dimensions of columns arg ({len(columns)}) must match data d

Error message

dimensions of columns arg ({len(columns)}) must match data dimensions ({len(data)})

What it means

_post_apply_columns renames already-constructed Series according to a `columns` argument after DataFrame assembly. If the number of supplied names differs from the number of Series in the data, this ValueError fires — the list/sequence counterpart of the schema-length checks, also guarding internal paths used after dict construction (from_dict reordering).

Source

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

        column_dtypes.update(schema_overrides)

    return column_names, column_dtypes


def _handle_columns_arg(
    data: list[PySeries],
    columns: Sequence[str] | None = None,
    *,
    from_dict: bool = False,
) -> list[PySeries]:
    """Rename data according to columns argument."""
    if columns is None:
        return data
    elif not data:
        return [pl.Series(name=c)._s for c in columns]
    elif len(data) != len(columns):
        msg = f"dimensions of columns arg ({len(columns)}) must match data dimensions ({len(data)})"
        raise ValueError(msg)

    if from_dict:
        series_map = {s.name(): s for s in data}
        if all((col in series_map) for col in columns):
            return [series_map[col] for col in columns]

    for i, c in enumerate(columns):
        if c != data[i].name():
            data[i] = data[i].clone()
            data[i].rename(c)

    return data


def _post_apply_columns(
    pydf: PyDataFrame,
    columns: SchemaDefinition | None,
    structs: dict[str, Struct] | None = None,

View on GitHub (pinned to df599052da)

Solutions

  1. Match the counts: pass exactly one name per column (`columns=["a", "b", "c"]`)
  2. Or name the Series themselves (`pl.Series("a", [1])`) and drop the columns argument
  3. Compute names from the data instead of hardcoding: `columns=[s.name for s in data]` or `[f"col_{i}" for i in range(len(data))]`

Example fix

# before
cols = [pl.Series("x", [1, 2]), pl.Series("y", [3, 4]), pl.Series("z", [5, 6])]
pl.DataFrame(cols)
# internal rename path with columns=["a", "b"] -> ValueError: dimensions of columns arg (2) must match data dimensions (3)

# after
pl.DataFrame(cols)  # keep the Series names: x, y, z
# or rename with matching count:
df = pl.DataFrame(cols)
df.columns = ["a", "b", "c"]
Defensive patterns

Strategy: validation

Validate before calling

import polars as pl

def apply_columns(data: list[pl.Series], columns: list[str] | None):
    if columns is not None and len(columns) != len(data):
        raise ValueError(f"{len(columns)} names for {len(data)} columns")
    return pl.DataFrame(data)

Type guard

def names_match_data(columns: list[str] | None, data) -> bool:
    """True if columns is None or its length equals the number of data columns."""
    return columns is None or len(columns) == len(data)

Try / catch

try:
    df = pl.DataFrame(data, columns=columns)  # or internal rename path
except ValueError as e:
    if "dimensions of columns arg" not in str(e):
        raise
    raise ValueError("column name list out of sync with data width — regenerate names") from e

Prevention

When it happens

Trigger: Constructing a DataFrame from a sequence of Series or prepared column data together with a `columns` name list of different length, e.g. three series with `columns=["a", "b"]`; any internal caller whose name list drifted from the data it passes.

Common situations: Reusable loader functions accepting both data and a name list where the data width varies between runs; concatenation/ETL helpers passing along a stale name list after a schema change.

Related errors


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