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

  1. Wrap scalars in a list whose length equals len(detections): set_data('frame', [42] * len(detections)).
  2. For numpy workflows pass np.asarray(...), e.g. np.full(len(detections), 42).
  3. 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

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


AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15). Data as JSON: /api/errors/43606f954a1457bf. Report an issue: GitHub.