{"record":{"id":"c9f89a546d625f96","repo":"roboflow/supervision","slug":"the-number-of-labels-len-labels-does-not-matc","errorCode":null,"errorMessage":"The number of labels ({len(labels)}) does not match the number of detections ({len(detections)}). Each detection should have exactly 1 label.","messagePattern":"The number of labels \\((.+?)\\) does not match the number of detections \\((.+?)\\)\\. Each detection should have exactly 1 label\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/supervision/annotators/utils.py","lineNumber":229,"sourceCode":"\n    return all_lines or [\"\"]\n\n\ndef _validate_labels(labels: list[str] | None, detections: Detections) -> None:\n    \"\"\"\n    Validates that the number of provided labels matches the number of detections.\n\n    Args:\n        labels: A list of labels, one for each detection. Can\n            be None.\n        detections: The detections to be labeled.\n\n    Raises:\n        ValueError: If `labels` is not None and its length does not match the number\n            of detections.\n    \"\"\"\n    if labels is not None and len(labels) != len(detections):\n        raise ValueError(\n            f\"The number of labels ({len(labels)}) does not match the \"\n            f\"number of detections ({len(detections)}). Each detection \"\n            f\"should have exactly 1 label.\"\n        )\n\n\n@deprecated(  # type: ignore[untyped-decorator]\n    target=_validate_labels,\n    deprecated_in=\"0.29.0\",\n    remove_in=\"0.32.0\",\n)\ndef validate_labels(labels: list[str] | None, detections: Detections) -> None:\n    void(labels, detections)\n\n\ndef get_labels_text(\n    detections: Detections, custom_labels: list[str] | None\n) -> list[str]:","sourceCodeStart":211,"sourceCodeEnd":247,"githubUrl":"https://github.com/roboflow/supervision/blob/7f254d9784d4c37e0f03cd89ddee164c8db099c0/src/supervision/annotators/utils.py#L211-L247","documentation":"Raised by _validate_labels() in supervision.annotators.utils when a non-None labels list passed to an annotator has a different length than the Detections object being annotated. Each detection must map to exactly one label; a mismatch means labels and boxes are misaligned, which would otherwise produce wrong or IndexError-prone rendering.","triggerScenarios":"Calling annotator.annotate(scene, detections, labels=labels) after filtering detections but not labels; building labels from class names of a previous frame in a tracker loop; passing a single string instead of a per-detection list; labeling detections.empty() with a nonempty list.","commonSituations":"Post-filtering with a confidence or class mask; tracked pipelines where detections change but a static label list is reused; multi-threaded consumers mutating detections between label generation and annotation; forgetting to wrap a single label in a list.","solutions":["Rebuild labels from the same detections you annotate: labels = [f'{names[c]} {conf:.2f}' for c, conf in zip(detections.class_id, detections.confidence)].","After any mask/slice of detections, apply the same mask to labels.","Pass labels=None when you do not want labels, instead of an empty list for nonempty detections.","Add an assert len(labels) == len(detections) right before annotate() while debugging."],"exampleFix":"// before\nmask = detections.confidence > 0.5\ndetections = detections[mask]\nannotator.annotate(scene, detections, labels=labels)  # stale labels\n\n// after\nmask = detections.confidence > 0.5\ndetections = detections[mask]\nlabels = [l for l, keep in zip(labels, mask) if keep]\nannotator.annotate(scene, detections, labels=labels)","handlingStrategy":"validation","validationCode":"assert len(detections) == len(labels), (len(detections), len(labels))\nannotator.annotate(scene, detections, labels=labels)\n\n# or derive labels from the same detections object:\nlabels = [str(c) for c in detections.class_id] if detections.class_id is not None else None","typeGuard":null,"tryCatchPattern":"try:\n    annotator.annotate(scene, detections, labels=labels)\nexcept ValueError as e:\n    if 'number of labels' in str(e):\n        labels = labels[: len(detections)]\n        annotator.annotate(scene, detections, labels=labels)\n    else:\n        raise","preventionTips":["Generate labels from the detections object being annotated, in the same expression scope.","After filtering detections, filter labels with the identical mask.","Add a length assert during development to catch desync early."],"tags":["annotators","validation","detections","labels"],"backgroundTag":null,"analyzedSha":"7f254d9784d4c37e0f03cd89ddee164c8db099c0","analyzedAt":"2026-08-15T05:13:01.950Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}