roboflow/supervision · error · ValueError
Class ID is required for YOLO annotations.
Error message
Class ID is required for YOLO annotations.
What it means
Raised by detections_to_yolo_annotations when iterating detections and a detection's class_id is None. YOLO annotation lines start with a class index, so a class-less Detections (e.g. from a tracker that dropped class_id or a manually built empty-class Detections) cannot be serialized.
Source
Thrown at src/supervision/dataset/formats/yolo.py:387
"`detections.data` with shape (N, 4, 2). Load OBB datasets via "
"`DetectionDataset.from_yolo(..., is_obb=True)` or set "
f"`detections.data['{ORIENTED_BOX_COORDINATES}']` "
"(shape (N, 4, 2)) before exporting."
)
if is_obb and detections.mask is not None:
warnings.warn(
"`detections.mask` is ignored when `is_obb=True`; "
"OBB annotations use corner coordinates from "
f"`detections.data['{ORIENTED_BOX_COORDINATES}']`.",
UserWarning,
stacklevel=2,
)
annotation: list[str] = []
for xyxy, mask, _, class_id, _, data in detections:
if class_id is None:
raise ValueError("Class ID is required for YOLO annotations.")
if not isinstance(class_id, (int, np.integer)):
raise ValueError(
f"Detections class_id must be an integer for YOLO export, "
f"got {type(class_id)!r}."
)
class_id_int = int(class_id)
if is_obb:
corners = np.asarray(data[ORIENTED_BOX_COORDINATES], dtype=np.float32)
if corners.shape != (4, 2):
raise ValueError(
f"OBB data for each detection must have shape (4, 2), "
f"got {corners.shape}. Ensure "
f"`detections.data['{ORIENTED_BOX_COORDINATES}']` has "
"shape (N, 4, 2) before exporting."
)
next_object = object_to_yolo(
xyxy=xyxy,View on GitHub (pinned to 7f254d9784)
Solutions
- Attach class ids when constructing: Detections(xyxy=..., class_id=np.array([0, 1], dtype=int)).
- If classes are genuinely unknown, assign a placeholder class (e.g. zeros) before export.
- Check any intermediate step (tracker, smoother, filter) that returns class_id=None and re-attach classes by tracker_id mapping.
Example fix
# before dets = sv.Detections(xyxy=xyxy) # no class_id lines = sv.detections_to_yolo_annotations(dets, image_shape=shape) # after dets = sv.Detections(xyxy=xyxy, class_id=np.zeros(len(xyxy), dtype=int)) lines = sv.detections_to_yolo_annotations(dets, image_shape=shape)
Defensive patterns
Strategy: type-guard
Validate before calling
import numpy as np
def ready_for_yolo_export(detections) -> bool:
"""YOLO export needs a non-None class_id array."""
return detections.class_id is not None Type guard
def has_class_id(detections) -> bool:
"""True when every detection carries an integer class id."""
return detections.class_id is not None and detections.class_id.dtype.kind in 'iu' Try / catch
try:
lines = sv.detections_to_yolo_annotations(dets, image_shape=shape)
except ValueError as e:
if 'Class ID is required' in str(e):
dets.class_id = np.zeros(len(dets), dtype=np.int64) # placeholder class
lines = sv.detections_to_yolo_annotations(dets, image_shape=shape)
else:
raise Prevention
- Always construct Detections with class_id when the output will be serialized.
- Check trackers/filters preserve class_id before export steps.
- For class-agnostic models, use a single-class id of 0.
When it happens
Trigger: Calling sv.detections_to_yolo_annotations(...) (or as_yolo_annotations on a dataset) where detections.class_id is None — commonly Detections created with only xyxy, or a class_id array that was deliberately cleared.
Common situations: Building Detections from raw model output without wiring class ids; using tracker output where class_id was not propagated; slicing/filtering detections and losing class_id; testing code with minimal Detections(xyxy=...) constructions.
Related errors
- `is_obb=True` requires `'{ORIENTED_BOX_COORDINATES}'` in `de
- Detections class_id must be an integer for YOLO export, got
- class_id is required for LabelMe export, but the provided De
- Detections must have class_id attribute.
- Detections must include class_id for COCO export.
AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15).
Data as JSON: /api/errors/ed5efb3e477bdeda.
Report an issue: GitHub.