pola-rs/polars · error · ValueError
invalid table style key: {key!r}
Error message
invalid table style key: {key!r} What it means
ValueError raised by _xl_setup_table_options during write_excel when table_style is a dict containing an unrecognized key. The dict form accepts exactly five keys — 'style', 'banded_columns', 'banded_rows', 'first_column', 'last_column' (mirroring Excel's table style options); anything else is a typo or an option that belongs elsewhere.
Source
Thrown at py-polars/src/polars/io/spreadsheet/_write_utils.py:556
return table_columns, column_formats, df # type: ignore[return-value]
def _xl_setup_table_options(
table_style: dict[str, Any] | str | None,
) -> tuple[dict[str, Any] | str | None, dict[str, Any]]:
"""Setup table options, distinguishing style name from other formatting."""
if isinstance(table_style, dict):
valid_options = (
"style",
"banded_columns",
"banded_rows",
"first_column",
"last_column",
)
for key in table_style:
if key not in valid_options:
msg = f"invalid table style key: {key!r}"
raise ValueError(msg)
table_options = table_style.copy()
table_style = table_options.pop("style", None)
else:
table_options = {}
return table_style, table_options
@overload
def _xl_worksheet_in_workbook(
wb: Workbook, ws: Worksheet, *, return_worksheet: Literal[False] = ...
) -> bool: ...
@overload
def _xl_worksheet_in_workbook(
wb: Workbook, ws: Worksheet, *, return_worksheet: Literal[True]
) -> Worksheet: ...
View on GitHub (pinned to df599052da)
Solutions
- Correct the key name: use only 'style', 'banded_columns', 'banded_rows', 'first_column', 'last_column'.
- If you meant the style name itself, pass table_style='Table Style Medium 9' as a plain string.
- Keep a frozenset of the valid keys and validate config dicts against it before calling write_excel.
Example fix
# before
pl.write_excel(df, table_style={'style': 'Table Style Medium 9', 'band_rows': True})
# after
pl.write_excel(df, table_style={'style': 'Table Style Medium 9', 'banded_rows': True}) Defensive patterns
Strategy: validation
Validate before calling
VALID_TABLE_STYLE_KEYS = {'style', 'banded_columns', 'banded_rows', 'first_column', 'last_column'}
if isinstance(table_style, dict):
bad = set(table_style) - VALID_TABLE_STYLE_KEYS
if bad:
raise ValueError(f'invalid table_style keys: {sorted(bad)}; valid: {sorted(VALID_TABLE_STYLE_KEYS)}')
pl.write_excel(df, table_style=table_style) Type guard
def is_valid_table_style(ts: object) -> bool:
if isinstance(ts, str):
return True
return isinstance(ts, dict) and set(ts) <= {'style', 'banded_columns', 'banded_rows', 'first_column', 'last_column'} Try / catch
try:
pl.write_excel(df, table_style=table_style)
except ValueError as e:
if 'invalid table style key' in str(e):
cleaned = {k: v for k, v in table_style.items() if k in VALID_TABLE_STYLE_KEYS} if isinstance(table_style, dict) else table_style
pl.write_excel(df, table_style=cleaned)
else:
raise Prevention
- Memorize the five keys: style, banded_columns, banded_rows, first_column, last_column.
- Pass a plain string when only the style name is needed.
- Define table_style dicts as module constants so typos surface in one reviewed place.
When it happens
Trigger: pl.write_excel(df, table_style={'style': 'Table Style Medium 9', 'banded_cols': True}) — misspelled 'banded_columns'; or keys like 'stripe_rows', 'style_name', 'autofilter' that are not part of the API.
Common situations: Hand-writing the options dict from memory of the Excel UI instead of the polars docs; translating openpyxl/xlsxwriter option names into this dict; version drift after the dict-based table_style interface was introduced.
Related errors
- supplying 'columns' param value is mandatory for sparklines
- cannot create a second {col!r} column
- sparkline data range/cols must all be adjacent
- invalid dtype_format value: {fmt!r} (expected format string,
- the given workbook object {wb.filename!r} is not the parent
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/152d7c3b670a8458.
Report an issue: GitHub.