roboflow/supervision · error · TypeError
Value must be a np.ndarray or a list
Error message
Value must be a np.ndarray or a list
What it means
Detections.set_data(key, value) stores per-detection metadata in the data dict, aligned row-by-row with xyxy. Only np.ndarray and list are accepted so length/shape validation can run; any other type (scalar, tuple, string, dict) raises this TypeError.
Source
Thrown at src/supervision/detection/core.py:2796
model = YOLO('yolov8s.pt')
result = model(image)[0]
detections = sv.Detections.from_ultralytics(result)
detections['names'] = [
model.model.names[class_id]
for class_id
in detections.class_id
]
```
Raises:
TypeError: If `value` is not a `np.ndarray` or `list`.
ValueError: If `value` has a length or shape incompatible with
the detection count.
"""
if not isinstance(value, (np.ndarray, list)):
raise TypeError("Value must be a np.ndarray or a list")
if isinstance(value, list):
value = np.array(value)
_validate_data({key: value}, len(self))
self.data[key] = value
@property
def area(self) -> npt.NDArray[np.generic]:
"""
Calculate the area of each detection in the set of object detections.
Selection order:
1. If ``mask`` is set, return the area of each mask.
2. Else, if ``data[ORIENTED_BOX_COORDINATES]`` is set, return the area of
the rotated body (shoelace formula on the four corners).
3. Otherwise, return the axis-aligned box area (``box_area``).View on GitHub (pinned to 7f254d9784)
Solutions
- Wrap scalars in a list whose length equals len(detections): set_data('frame', [42] * len(detections)).
- For numpy workflows pass np.asarray(...), e.g. np.full(len(detections), 42).
- If the value is genuinely per-set (one object for the whole Detections, like video metadata), use Detections.metadata, not set_data.
Example fix
# before
detections.set_data('camera_id', 3) # TypeError
# after
detections.set_data('camera_id', np.full(len(detections), 3)) Defensive patterns
Strategy: type-guard
Validate before calling
import numpy as np
def set_data_safe(dets: sv.Detections, key: str, value) -> None:
if not isinstance(value, (np.ndarray, list)):
value = [value] * len(dets)
dets.set_data(key, value)
set_data_safe(detections, 'camera_id', 3) Type guard
def is_set_data_value(value) -> bool:
import numpy as np
return isinstance(value, (np.ndarray, list)) Prevention
- Broadcast scalars to len(detections) lists yourself
- Use Detections.metadata for whole-set state
- Remember set_data is per-row, aligned with xyxy
When it happens
Trigger: Calling detections.set_data('track_color', (255, 0, 0)) or set_data('frame', 42), set_data('name', 'car') — any non-ndarray/list value, including tuples and plain scalars.
Common situations: Trying to attach a single global attribute (frame number, color, label) to all detections and passing the raw scalar; passing a tuple because it 'looks like an array'; assuming set_data accepts anything like a Python dict update.
Related errors
- All metadata dictionaries must have the same keys to merge.
- Conflicting metadata for key: '{key}': {type(value)}, {type(
- Conflicting metadata for key: '{key}'.
- Value for key '{key}' must be a list or np.ndarray
- Number of colors ({len(colors)}) must match number of key po
AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15).
Data as JSON: /api/errors/43606f954a1457bf.
Report an issue: GitHub.