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

  1. Remove include_key when partitioning only by size: pl.PartitionBy('out/', max_rows_per_file=1000).
  2. Or add a key so include_key becomes meaningful: pl.PartitionBy('out/', key='region', include_key=False).
  3. 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

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


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