{"record":{"id":"ff3f6a321ac37ec6","repo":"headroomlabs-ai/headroom","slug":"ccr-originals-list-length-len-ccr-originals-doe","errorCode":null,"errorMessage":"ccr_originals list length {len(ccr_originals)} does not match contents length {n}","messagePattern":"ccr_originals list length (.+?) does not match contents length (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"headroom/transforms/kompress_compressor.py","lineNumber":1862,"sourceCode":"            return []\n        t_deadline = time.perf_counter() if _deadline_started_at is None else _deadline_started_at\n\n        # Normalize target_ratio to a per-text list\n        if isinstance(target_ratio, list):\n            if len(target_ratio) != n:\n                raise ValueError(\n                    f\"target_ratio list length {len(target_ratio)} does not match \"\n                    f\"contents length {n}\"\n                )\n            ratios: list[float | None] = list(target_ratio)\n        else:\n            ratios = [target_ratio] * n\n\n        # Normalize ccr_originals to a per-text list (CCR stores these instead of\n        # the possibly tag-protected ``contents`` entries; see ``compress``).\n        if ccr_originals is not None:\n            if len(ccr_originals) != n:\n                raise ValueError(\n                    f\"ccr_originals list length {len(ccr_originals)} does not match \"\n                    f\"contents length {n}\"\n                )\n            ccr_sources: list[str | None] = list(ccr_originals)\n        else:\n            ccr_sources = [None] * n\n\n        if getattr(self, \"_degraded_reason\", None) is not None:\n            return [self._passthrough(c, len(c.split())) for c in contents]\n\n        # Fast path: on backends where batch-dim parallelism does NOT help\n        # (ONNX CPU, PyTorch CPU), fall back to sequential `compress()`\n        # internally. This keeps the public API consistent while avoiding the\n        # per-item slowdown measured on ONNX CPU (~0.7-0.9x vs sequential).\n        # GPU users still benefit from the batched forward pass below.\n        if self._should_use_sequential_fallback():\n            return [\n                self.compress(","sourceCodeStart":1844,"sourceCodeEnd":1880,"githubUrl":"https://github.com/headroomlabs-ai/headroom/blob/322425c43bffde1ed0b64fecf3cf5951565dd82b/headroom/transforms/kompress_compressor.py#L1844-L1880","documentation":"Raised by the batched Kompress path when `ccr_originals` (the un-tag-protected original texts that CCR stores instead of the possibly tag-wrapped `contents` entries) is supplied as a list whose length differs from `len(contents)`. Like the target_ratio check, it enforces a strict per-text alignment before processing starts.","triggerScenarios":"Calling the batched compress API with `ccr_originals=[...]` where the list was built for a different number of texts than `contents` — e.g. contents were split, deduplicated, or extended after the originals list was captured.","commonSituations":"CCR/tag-protected pipelines where the caller keeps originals in a separate list and mutates `contents` (appending system messages, filtering empties) without applying the same operation to `ccr_originals`; or copying an example that omitted `ccr_originals` semantics and supplying a single-element list.","solutions":["Align the lists: `ccr_originals` must have exactly `len(contents)` entries, positionally matching each content","Derive both lists in the same loop/comprehension over your source records so filtering or reordering always applies to both","If no CCR originals apply, pass `ccr_originals=None` (the default) rather than an empty or stub list"],"exampleFix":"# before\nresults = kompress.compress_batch(contents, ccr_originals=originals)  # len mismatch\n\n# after\npairs = [(c, o) for c, o in zip(contents, originals) if keep(c)]\nresults = kompress.compress_batch([c for c, _ in pairs], ccr_originals=[o for _, o in pairs])","handlingStrategy":"validation","validationCode":"def check_ccr_alignment(contents: list[str], ccr_originals) -> None:\n    if ccr_originals is not None and len(ccr_originals) != len(contents):\n        raise ValueError(\n            f\"ccr_originals has {len(ccr_originals)} entries for \"\n            f\"{len(contents)} contents\"\n        )\n\ncheck_ccr_alignment(contents, ccr_originals)\nresults = kompress.compress_batch(contents, ccr_originals=ccr_originals)","typeGuard":"def ccr_aligned(contents: list[str], ccr) -> bool:\n    return ccr is None or len(ccr) == len(contents)","tryCatchPattern":"try:\n    results = kompress.compress_batch(contents, ccr_originals=ccr_originals)\nexcept ValueError as e:\n    if \"ccr_originals list length\" in str(e):\n        results = kompress.compress_batch(contents)  # omit originals if truly optional\n    else:\n        raise","preventionTips":["Store (content, ccr_original) as paired tuples/objects so the lists cannot drift","Apply the same filter/map operations to both lists, once, in one place","Pass ccr_originals=None when the batch carries no tag-protected entries"],"tags":["validation","batch-api","kompress","ccr","precondition"],"backgroundTag":null,"analyzedSha":"322425c43bffde1ed0b64fecf3cf5951565dd82b","analyzedAt":"2026-08-15T01:03:05.481Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}