roboflow/supervision · error · ValueError
Detection annotation for image {image_path} contains non-int
Error message
Detection annotation for image {image_path} contains non-integer class_id values with dtype {class_ids.dtype}. What it means
Raised by the DetectionDataset constructor during annotation validation when an annotation's class_id array has a non-integer dtype (e.g. float32). The constructor later indexes the class-name array with class_ids (np_classes[class_ids]) and fills CLASS_NAME_DATA_FIELD, which requires integer indices; float class ids would either fail indexing or hide data-quality bugs.
Source
Thrown at src/supervision/dataset/core.py:115
) -> None:
self.classes = classes
if set(images) != set(annotations):
raise ValueError(
"The keys of the images and annotations dictionaries must match."
)
self.annotations = {
image_path: deepcopy(annotation)
for image_path, annotation in annotations.items()
}
np_classes = np.array(self.classes)
for image_path, annotation in self.annotations.items():
class_ids = annotation.class_id
if class_ids is None:
continue
if not np.issubdtype(class_ids.dtype, np.integer):
raise ValueError(
f"Detection annotation for image {image_path!r} contains "
f"non-integer class_id values with dtype {class_ids.dtype}."
)
invalid_class_ids = class_ids[
(class_ids < 0) | (class_ids >= len(self.classes))
]
if len(invalid_class_ids) > 0:
valid_range = (
"empty"
if len(self.classes) == 0
else f"[0, {len(self.classes) - 1}]"
)
raise ValueError(
f"Detection annotation for image {image_path!r} contains "
f"class_id {int(invalid_class_ids[0])}, outside the valid "
f"range {valid_range} for {len(self.classes)} classes."
)View on GitHub (pinned to 7f254d9784)
Solutions
- Cast class_id to an integer dtype when building Detections: class_id=np.array(ids, dtype=np.int64).
- If parsing from JSON/COCO, map category ids through int(): np.array([int(a['category_id']) for a in anns], dtype=np.int64).
- Audit annotations before construction: assert all Detections.class_id is None or np.issubdtype(d.class_id.dtype, np.integer).
Example fix
// before cls_ids = np.array([0.0, 2.0, 1.0]) # float dtype from JSON parsing dets = sv.Detections(xyxy=boxes, class_id=cls_ids) // after cls_ids = np.array([0, 2, 1], dtype=np.int64) dets = sv.Detections(xyxy=boxes, class_id=cls_ids)
Defensive patterns
Strategy: type-guard
Validate before calling
for path, dets in annotations.items():
if dets.class_id is not None and not np.issubdtype(dets.class_id.dtype, np.integer):
annotations[path] = replace(dets, class_id=dets.class_id.astype(np.int64))
ds = DetectionDataset(classes=classes, images=images, annotations=annotations) Type guard
def integer_class_ids(dets: sv.Detections) -> bool:
return dets.class_id is None or np.issubdtype(dets.class_id.dtype, np.integer) Prevention
- Always build class_id with an explicit integer dtype: np.array(ids, dtype=np.int64).
- After parsing COCO/JSON (all floats), cast ids through int() immediately.
- Add a lint-style pass over annotations before dataset construction.
When it happens
Trigger: Constructing DetectionDataset with annotations whose class_id came from JSON/COCO parsing that produced floats (e.g. [[0.0], [2.0]]) and was cast to a float ndarray instead of int.
Common situations: Loading COCO annotations via the json module (all numbers are floats) and building Detections without astype(int); converting from CSVs that parse ids as floats; mixing dtypes when hand-assembling annotations.
Related errors
- Detection annotation for image {image_path} contains class_i
- Detections must have class_id attribute.
- Detections class_id must be a subset of source_to_target_map
- KeyPoints class_id must be given for NMS to be executed. If
- Class {class_name} not found in target classes. source_class
AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15).
Data as JSON: /api/errors/99632d5e5fcad9f1.
Report an issue: GitHub.