pola-rs/polars · error · ValueError

supplying 'columns' param value is mandatory for sparklines

Error message

supplying 'columns' param value is mandatory for sparklines

What it means

ValueError raised by _inject_sparklines during write_excel when a sparkline definition supplies no data columns. Each sparkline entry must reference the frame columns it summarizes — either the dict form {'columns': [...]} or the bare list form ['a','b']. A missing 'columns' key, an empty list, or other falsy value leaves the sparkline with no data range.

Source

Thrown at py-polars/src/polars/io/spreadsheet/_write_utils.py:302


def _xl_inject_sparklines(
    ws: Worksheet,
    df: DataFrame,
    table_start: tuple[int, int],
    col: str,
    *,
    include_header: bool,
    params: Sequence[str] | dict[str, Any],
) -> None:
    """Inject sparklines into (previously-created) empty table columns."""
    from xlsxwriter.utility import xl_rowcol_to_cell

    m: dict[str, Any] = {}
    data_cols = params.get("columns") if isinstance(params, dict) else params
    if not data_cols:
        msg = "supplying 'columns' param value is mandatory for sparklines"
        raise ValueError(msg)
    elif not _adjacent_cols(df, data_cols, min_max=m):
        msg = "sparkline data range/cols must all be adjacent"
        raise RuntimeError(msg)

    spk_row, spk_col, _, _ = _xl_column_range(
        df, table_start, col, include_header=include_header, as_range=False
    )
    data_start_col = table_start[1] + m["min"]["idx"]
    data_end_col = table_start[1] + m["max"]["idx"]

    if not isinstance(params, dict):
        options = {}
    else:
        # strip polars-specific params before passing to xlsxwriter
        options = {
            name: val
            for name, val in params.items()
            if name not in ("columns", "insert_after", "insert_before")

View on GitHub (pinned to df599052da)

Solutions

  1. Add the 'columns' entry: sparklines={'spark': {'columns': ['a', 'b', 'c'], 'insert_before': 'd'}}.
  2. Or use the list shorthand when no other options are needed: sparklines={'spark': ['a', 'b', 'c']}.
  3. Validate every sparkline config resolves to a non-empty column list before calling write_excel.

Example fix

# before
pl.write_excel(df, sparklines={'spark': {'insert_before': 'd'}})

# after
pl.write_excel(df, sparklines={'spark': {'columns': ['a', 'b', 'c'], 'insert_before': 'd'}})
Defensive patterns

Strategy: validation

Validate before calling

for name, spec in sparklines.items():
    cols = spec.get('columns') if isinstance(spec, dict) else spec
    if not cols:
        raise ValueError(f"sparkline {name!r} needs a non-empty 'columns' value")
pl.write_excel(df, sparklines=sparklines)

Try / catch

try:
    pl.write_excel(df, sparklines=sparklines)
except ValueError as e:
    if "'columns' param value is mandatory" in str(e):
        fixed = {k: ({'columns': list(v), **{}} if not isinstance(v, dict) and v else v) for k, v in sparklines.items()}
        pl.write_excel(df, sparklines=fixed)
    else:
        raise

Prevention

When it happens

Trigger: pl.write_excel(df, sparklines={'spark': {'insert_before': 'b'}}) (dict without 'columns'), or sparklines={'spark': []} (empty list). Only style/position options were provided.

Common situations: Using the dict form to set options like insert_before and forgetting the mandatory 'columns' entry; generating sparkline configs programmatically where the columns list comes back empty (bad key name, empty selection).

Related errors


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