headroomlabs-ai/headroom · error · ValueError

target_ratio list length {len(target_ratio)} does not match

Error message

target_ratio list length {len(target_ratio)} does not match contents length {n}

What it means

Raised by the batched Kompress compression path when an explicitly passed `target_ratio` list does not have exactly one entry per item in `contents`. The API accepts either a single ratio applied to all texts or a per-text list; the length check enforces that 1:1 correspondence before any work is dispatched. It is a pure caller-side argument validation error.

Source

Thrown at headroom/transforms/kompress_compressor.py:1850

        Notes:
            On the batched GPU path, scoring uses ``get_scores`` uniformly
            (threshold at 0.5 when ``target_ratio`` is ``None``). This
            matches the ONNX non-batched behavior exactly. The PyTorch
            non-batched path applies an additional borderline + span-boost
            rule, so results may differ by a small fraction of tokens on
            ``target_ratio=None`` calls via the batched path vs direct
            :meth:`compress` on PyTorch. Call :meth:`compress` directly if
            the exact PyTorch borderline behavior is required.
        """
        n = len(contents)
        if n == 0:
            return []
        t_deadline = time.perf_counter() if _deadline_started_at is None else _deadline_started_at

        # Normalize target_ratio to a per-text list
        if isinstance(target_ratio, list):
            if len(target_ratio) != n:
                raise ValueError(
                    f"target_ratio list length {len(target_ratio)} does not match "
                    f"contents length {n}"
                )
            ratios: list[float | None] = list(target_ratio)
        else:
            ratios = [target_ratio] * n

        # Normalize ccr_originals to a per-text list (CCR stores these instead of
        # the possibly tag-protected ``contents`` entries; see ``compress``).
        if ccr_originals is not None:
            if len(ccr_originals) != n:
                raise ValueError(
                    f"ccr_originals list length {len(ccr_originals)} does not match "
                    f"contents length {n}"
                )
            ccr_sources: list[str | None] = list(ccr_originals)
        else:
            ccr_sources = [None] * n

View on GitHub (pinned to 322425c43b)

Solutions

  1. Make `len(target_ratio)` equal `len(contents)` — build both lists from the same iteration/filter so they cannot diverge
  2. If every text should get the same ratio, pass a scalar (`target_ratio=0.5`) instead of a list — the code replicates it across the batch
  3. If ratios were computed per-text earlier, recompute or re-index them against the current `contents` (e.g. zip contents with their metadata before calling)

Example fix

# before
ratios = [0.5] * 2
results = kompress.compress_batch([a, b, c], target_ratio=ratios)

# after
results = kompress.compress_batch([a, b, c], target_ratio=0.5)
# or: ratios = [0.5] * len(contents)
Defensive patterns

Strategy: validation

Validate before calling

def check_batch_args(contents: list[str], target_ratio) -> None:
    if isinstance(target_ratio, list) and len(target_ratio) != len(contents):
        raise ValueError(
            f"target_ratio has {len(target_ratio)} entries for "
            f"{len(contents)} contents"
        )

check_batch_args(contents, target_ratio)
results = kompress.compress_batch(contents, target_ratio=target_ratio)

Type guard

def is_aligned_ratio_list(contents: list[str], tr) -> bool:
    return not isinstance(tr, list) or len(tr) == len(contents)

Try / catch

try:
    results = kompress.compress_batch(contents, target_ratio=ratios)
except ValueError as e:
    if "target_ratio list length" in str(e):
        ratios = [base_ratio] * len(contents)  # or rebuild per-text ratios
        results = kompress.compress_batch(contents, target_ratio=ratios)
    else:
        raise

Prevention

When it happens

Trigger: Calling `compress_batch(contents, target_ratio=[0.5, 0.3])` (or the batched `compress` overload) with a list whose length differs from `len(contents)` — e.g. 3 contents but 2 ratios, or reusing a ratios list computed for a previous, different-sized batch.

Common situations: Building the ratio list in a loop with an off-by-one, filtering `contents` (e.g. dropping empty strings) without filtering the parallel ratio list, or passing a shared ratio list across batches of varying size instead of the scalar form.

Related errors


AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15). Data as JSON: /api/errors/66cff8bc6bb681d4. Report an issue: GitHub.