roboflow/supervision · error · ValueError
'{CLASS_NAME_DATA_FIELD}' has {len(class_names)} entries but
Error message
'{CLASS_NAME_DATA_FIELD}' has {len(class_names)} entries but detections has {len(detections)} - the two must stay aligned. What it means
Raised while resolving label text (util that backs `LabelAnnotator`/`RichLabelAnnotator`) when `detections.data[CLASS_NAME_DATA_FIELD]` has a different length than `detections` itself. `Detections.data` is normally kept aligned by the dataclass validator, but a caller that mutates `detections.data` directly (e.g. assigning a new array) can break alignment; the library fails loudly instead of dropping or duplicating labels.
Source
Thrown at src/supervision/annotators/utils.py:277
Returns:
A list of text labels for each detection.
Raises:
ValueError: If `class_name` or `class_id` is present but its length
does not match the number of detections (e.g. `detections.data`
was mutated directly, bypassing `Detections` alignment checks).
"""
if custom_labels is not None:
return custom_labels
if CLASS_NAME_DATA_FIELD in detections.data:
class_names = detections.data[CLASS_NAME_DATA_FIELD]
# `Detections.data` is normally kept aligned with `xyxy` by the
# dataclass's own validation, but a caller can bypass it by mutating
# `detections.data` directly. Fail loudly rather than silently
# dropping or duplicating labels.
if len(class_names) != len(detections):
raise ValueError(
f"'{CLASS_NAME_DATA_FIELD}' has {len(class_names)} entries "
f"but detections has {len(detections)} - the two must stay "
"aligned."
)
return [str(v) for v in class_names]
if detections.class_id is not None:
if len(detections.class_id) != len(detections):
raise ValueError(
f"'class_id' has {len(detections.class_id)} entries but "
f"detections has {len(detections)} - the two must stay "
"aligned."
)
return [str(v) for v in detections.class_id]
return [str(i) for i in range(len(detections))]
def snap_boxes(
xyxy: npt.NDArray[np.float32],View on GitHub (pinned to 7f254d9784)
Solutions
- Rebuild the data arrays after slicing: slice `detections` first, then assign `detections.data[CLASS_NAME_DATA_FIELD] = class_names[keep_mask]` with the same mask.
- Set the field at construction time via the connector (most `from_*` connectors populate it from the model's class names) so alignment is enforced by the dataclass validator.
- Use `Detections.__getitem__` (slicing) rather than rebuilding Detections manually — it re-indexes `.data` for you.
Example fix
# before names = result.names # all detections detections = detections[detections.class_id == 0] # now shorter detections.data[CLASS_NAME_DATA_FIELD] = names # length mismatch -> ValueError # after keep = detections.class_id == 0 detections.data[CLASS_NAME_DATA_FIELD] = detections.data[CLASS_NAME_DATA_FIELD][keep] detections = detections[keep]
Defensive patterns
Strategy: validation
Validate before calling
if CLASS_NAME_DATA_FIELD in detections.data:
assert len(detections.data[CLASS_NAME_DATA_FIELD]) == len(detections), (
"class-name data drifted out of alignment with detections"
) Prevention
- Never mutate detections.data directly with arrays from a different-length source.
- Set CLASS_NAME_DATA_FIELD at construction or via connectors so the dataclass validator enforces alignment.
- Slice detections with detections[mask] — it re-indexes .data consistently.
When it happens
Trigger: Doing `detections.data[CLASS_NAME_DATA_FIELD] = np.array(['cat', 'dog'])` after slicing detections down to 3 rows; assigning a class-name array built from the unsliced model result while `detections` was filtered via `detections[np.array([0, 2])]`; manually constructing Detections then appending to `.data` post-hoc.
Common situations: Post-processing pipelines that slice detections for zone filtering or confidence thresholds but update `data` from the pre-slice result; porting code that stored labels in a parallel Python list that drifted out of sync; debugging sessions that mutate `.data` interactively.
Related errors
- 'class_id' has {len(detections.class_id)} entries but detect
- The number of labels ({len(labels)}) does not match the numb
- Length of color lookup {len(color_lookup)} does not match le
- The number of icon paths provided ({len(icon_path)}) does no
- The length of custom_values must match the number of detecti
AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15).
Data as JSON: /api/errors/fd9ef8652df4d295.
Report an issue: GitHub.