roboflow/supervision · error · ValueError
Detections must include class_id for COCO export.
Error message
Detections must include class_id for COCO export.
What it means
Raised by detections_to_coco_annotations when iterating Detections and a detection has class_id=None. COCO annotations require a category_id for every object, so a Detections without class_id cannot be serialized to the COCO format. The check runs per-detection inside the export loop.
Source
Thrown at src/supervision/dataset/formats/coco.py:305
... )
>>> detections = Detections(
... xyxy=np.array([[0, 0, 10, 10]], dtype=np.float32),
... class_id=np.array([0], dtype=int),
... )
>>> annotations, next_id = detections_to_coco_annotations(
... detections=detections, image_id=1, annotation_id=1
... )
>>> annotations[0]["category_id"]
1
>>> next_id
2
```
"""
coco_annotations: list[CocoDict] = []
for xyxy, mask, _, class_id, _, data in detections:
if class_id is None:
raise ValueError("Detections must include class_id for COCO export.")
box_width, box_height = xyxy[2] - xyxy[0], xyxy[3] - xyxy[1]
segmentation: list[list[float]] | dict[str, list[int]] = []
if mask is not None:
mask_bool = mask
if "iscrowd" in data:
iscrowd = int(np.asarray(data["iscrowd"]).item())
else:
iscrowd = int(
contains_holes(mask=mask_bool)
or contains_multiple_segments(mask=mask_bool)
)
if iscrowd:
segmentation = {
"counts": cast(
list[int], mask_to_rle(mask=mask_bool, compressed=False)
),
"size": list(mask.shape[:2]),View on GitHub (pinned to 7f254d9784)
Solutions
- Provide class_id when constructing Detections: sv.Detections(xyxy=boxes, confidence=conf, class_id=class_ids).
- If all boxes belong to one known class, synthesize class_id=np.zeros(len(boxes), dtype=int).
- Check detections.class_id is not None before calling the COCO export and fail early with your own message.
Example fix
// before detections = sv.Detections(xyxy=boxes, confidence=conf) save_coco_annotations(dataset=ds, annotation_path="out.json") # ds built from class_id-less detections // after detections = sv.Detections(xyxy=boxes, confidence=conf, class_id=np.zeros(len(boxes), dtype=int))
Defensive patterns
Strategy: type-guard
Validate before calling
if detections.class_id is None or len(detections) == 0 and detections.class_id is None:
raise ValueError("Attach class_id before COCO export")
# single-class fallback:
# detections = sv.Detections(xyxy=detections.xyxy, confidence=detections.confidence,
# class_id=np.zeros(len(detections), dtype=int)) Type guard
def has_class_id(dets: sv.Detections) -> bool:
"""True when every detection carries a class id."""
return dets.class_id is not None and len(dets.class_id) == len(dets) Try / catch
try:
save_coco_annotations(dataset=ds, annotation_path=p)
except ValueError as exc:
if "class_id" in str(exc):
raise RuntimeError("Model produced class-agnostic detections; map them to a class first") from exc
raise Prevention
- Always construct Detections with class_id alongside xyxy.
- After slicing/filtering Detections, re-check that class_id survived (it is index-aligned).
- For class-agnostic pipelines, default to class_id=zeros and a single-element classes list.
When it happens
Trigger: Calling sv.Detections with xyxy/confidence but no class_id (e.g. raw model output from a detector run in NMS-only mode, or a manually built Detections), then passing it to save_coco_annotations / detections_to_coco_annotations / DetectionDataset save path that ultimately writes COCO.
Common situations: Using detections produced by a tracker or a model that drops class_id; constructing Detections from custom boxes for dataset conversion; filtering detections and losing the class_id array.
Related errors
- class_id is required for CreateML export, but the provided D
- Detections must include class_id for Pascal VOC export.
- Detections must have class_id attribute.
- Detection annotation for image {image_path} contains non-int
- Detection annotation for image {image_path} contains class_i
AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15).
Data as JSON: /api/errors/ccc65f4ecf635aa4.
Report an issue: GitHub.