pola-rs/polars · error · ValueError
cannot use 'include_key' without specifying 'key'
Error message
cannot use 'include_key' without specifying 'key'
What it means
ValueError raised by the PartitionBy constructor when include_key is set but key is None. include_key controls whether the partition-key column(s) are also written into the output files; with no key there is nothing to include or omit, so the option is meaningless and rejected at construction time.
Source
Thrown at py-polars/src/polars/io/partition.py:115
) -> None:
msg = "`PartitionBy` functionality is considered unstable"
issue_unstable_warning(msg)
if (
key is None
and max_rows_per_file is None
and approximate_bytes_per_file == "auto"
):
msg = (
"at least one of "
"('key', 'max_rows_per_file', 'approximate_bytes_per_file') "
"must be specified for PartitionBy"
)
raise ValueError(msg)
if key is None and include_key is not None:
msg = "cannot use 'include_key' without specifying 'key'"
raise ValueError(msg)
base_path = str(base_path)
if approximate_bytes_per_file == "auto":
approximate_bytes_per_file = (
4_294_967_295 if max_rows_per_file is None else None
)
if approximate_bytes_per_file is None:
approximate_bytes_per_file = (1 << 64) - 1
self._pl_partition_by = _PartitionByInner(
base_path=base_path,
file_path_provider=file_path_provider,
key=_parse_to_pyexpr_list(key) if key is not None else None,
include_key=include_key,
max_rows_per_file=max_rows_per_file,
approximate_bytes_per_file=approximate_bytes_per_file,View on GitHub (pinned to df599052da)
Solutions
- Remove include_key when partitioning only by size: pl.PartitionBy('out/', max_rows_per_file=1000).
- Or add a key so include_key becomes meaningful: pl.PartitionBy('out/', key='region', include_key=False).
- Audit shared config dicts so include_key is only injected when a key is present.
Example fix
# before
pl.PartitionBy('out/', max_rows_per_file=1_000_000, include_key=True)
# after
pl.PartitionBy('out/', max_rows_per_file=1_000_000)
# or
pl.PartitionBy('out/', key='region', include_key=True) Defensive patterns
Strategy: validation
Validate before calling
cfg = dict(partition_cfg)
if cfg.get('key') is None:
cfg.pop('include_key', None) # meaningless without a key
pl.PartitionBy(base_path, **cfg) Try / catch
try:
pl.PartitionBy(out_dir, **cfg)
except ValueError as e:
if "without specifying 'key'" in str(e):
cfg.pop('include_key', None)
pl.PartitionBy(out_dir, **cfg)
else:
raise Prevention
- Only populate include_key in configs that also populate key.
- Model partition config as a dataclass where include_key validity is checked in __post_init__.
- Size-based chunking and include_key are unrelated — do not copy options between them blindly.
When it happens
Trigger: pl.PartitionBy('out/', max_rows_per_file=1000, include_key=True) — any size-only or byte-only partitioning combined with include_key.
Common situations: Copy-pasting a keyed PartitionBy config and removing the key while keeping include_key; setting include_key=True 'for completeness' when only chunking by size; config templates that always populate include_key.
Related errors
- at least one of ('key', 'max_rows_per_file', 'approximate_by
- write_parquet with `use_pyarrow=True` allows only boolean va
- write_parquet with `use_pyarrow=True` cannot be combined wit
- `sink_parquet` is not supported by {type(self).__name__}
- write_table: table format of {catalog_name}.{namespace}.{tab
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/a436fb73f7b8f1bc.
Report an issue: GitHub.