{"record":{"id":"c0906daee36b3a4d","repo":"roboflow/supervision","slug":"detection-annotation-for-image-image-path-contai-c0906d","errorCode":null,"errorMessage":"Detection annotation for image {image_path} contains class_id {int(invalid_class_ids[0])}, outside the valid range {valid_range} for {len(self.classes)} classes.","messagePattern":"Detection annotation for image (.+?) contains class_id (.+?), outside the valid range (.+?) for (.+?) classes\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/supervision/dataset/core.py","lineNumber":129,"sourceCode":"            class_ids = annotation.class_id\n            if class_ids is None:\n                continue\n            if not np.issubdtype(class_ids.dtype, np.integer):\n                raise ValueError(\n                    f\"Detection annotation for image {image_path!r} contains \"\n                    f\"non-integer class_id values with dtype {class_ids.dtype}.\"\n                )\n\n            invalid_class_ids = class_ids[\n                (class_ids < 0) | (class_ids >= len(self.classes))\n            ]\n            if len(invalid_class_ids) > 0:\n                valid_range = (\n                    \"empty\"\n                    if len(self.classes) == 0\n                    else f\"[0, {len(self.classes) - 1}]\"\n                )\n                raise ValueError(\n                    f\"Detection annotation for image {image_path!r} contains \"\n                    f\"class_id {int(invalid_class_ids[0])}, outside the valid \"\n                    f\"range {valid_range} for {len(self.classes)} classes.\"\n                )\n\n            annotation.data[CLASS_NAME_DATA_FIELD] = np_classes[class_ids]\n\n        # Eliminate duplicates while preserving order\n        self.image_paths = list(dict.fromkeys(images))\n\n        self._images_in_memory: dict[str, npt.NDArray[np.uint8]] = {}\n        if isinstance(images, dict):\n            self._images_in_memory = images\n            warn_deprecated(\n                \"Passing a `Dict[str, np.ndarray]` into `DetectionDataset` is \"\n                \"deprecated in `0.30.0` and will be removed in `0.33.0`. Use \"\n                \"a list of paths `List[str]` instead.\"\n            )","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/roboflow/supervision/blob/7f254d9784d4c37e0f03cd89ddee164c8db099c0/src/supervision/dataset/core.py#L111-L147","documentation":"Raised by the DetectionDataset constructor when an annotation contains a class_id outside [0, len(classes)-1]. Right after this check the constructor does np_classes[class_ids] to attach class-name metadata; an out-of-range id would raise a cryptic IndexError instead, so it validates first and reports the offending image, id, and valid range. An empty classes list yields 'empty' as the valid range.","triggerScenarios":"Constructing DetectionDataset(classes=['cat','dog'], ...) with an annotation containing class_id=3 (valid range is [0,1]); or passing annotations with ids offset by 1; or building the dataset with an empty classes list while annotations carry ids.","commonSituations":"COCO datasets where category_id is not contiguous (e.g. ids 1,3,7 used directly without remapping to indices); merging datasets with different class orderings; forgetting that classes=[] invalidates every id; off-by-one from 1-based id schemes.","solutions":["Remap raw category ids to contiguous 0-based indices using the classes list (the same logic as build_class_index_mapping) before constructing Detections.","Extend the classes list so it covers every id present: classes must have at least max(class_id)+1 entries.","Drop or fix annotations with ids beyond your class list."],"exampleFix":"// before\nclasses = ['cat', 'dog']\ndets = sv.Detections(xyxy=boxes, class_id=np.array([1, 3, 7]))  # 3, 7 out of range\nds = DetectionDataset(classes=classes, images=paths, annotations=anns)\n\n// after\n# remap sparse COCO-style ids to contiguous indices\ncat_to_idx = {c: i for i, c in enumerate(['cat', 'dog', 'horse', ...])}\ndets = sv.Detections(xyxy=boxes, class_id=np.array([cat_to_idx[c] for c in ['dog', 'horse', ...]]))\nds = DetectionDataset(classes=list(cat_to_idx), images=paths, annotations=anns)","handlingStrategy":"validation","validationCode":"for path, dets in annotations.items():\n    if dets.class_id is not None and len(dets.class_id) and (dets.class_id.max() >= len(classes) or dets.class_id.min() < 0):\n        raise ValueError(f\"{path}: class_id outside [0, {len(classes) - 1}]\")\nds = DetectionDataset(classes=classes, images=images, annotations=annotations)","typeGuard":"def class_ids_in_range(dets: sv.Detections, num_classes: int) -> bool:\n    if dets.class_id is None:\n        return True\n    return bool(np.all((dets.class_id >= 0) & (dets.class_id < num_classes)))","tryCatchPattern":null,"preventionTips":["Remap sparse COCO category ids to contiguous 0-based indices before building Detections.","Ensure the classes list covers max(class_id) + 1 entries.","Never construct a dataset with classes=[] while annotations carry class ids."],"tags":["dataset","class-id","out-of-range","coco","validation"],"backgroundTag":null,"analyzedSha":"7f254d9784d4c37e0f03cd89ddee164c8db099c0","analyzedAt":"2026-08-15T05:13:01.950Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}