{"record":{"id":"43606f954a1457bf","repo":"roboflow/supervision","slug":"value-must-be-a-np-ndarray-or-a-list-43606f","errorCode":null,"errorMessage":"Value must be a np.ndarray or a list","messagePattern":"Value must be a np\\.ndarray or a list","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/supervision/detection/core.py","lineNumber":2796,"sourceCode":"            model = YOLO('yolov8s.pt')\n\n            result = model(image)[0]\n            detections = sv.Detections.from_ultralytics(result)\n\n            detections['names'] = [\n                 model.model.names[class_id]\n                 for class_id\n                 in detections.class_id\n             ]\n            ```\n\n        Raises:\n            TypeError: If `value` is not a `np.ndarray` or `list`.\n            ValueError: If `value` has a length or shape incompatible with\n                the detection count.\n        \"\"\"\n        if not isinstance(value, (np.ndarray, list)):\n            raise TypeError(\"Value must be a np.ndarray or a list\")\n\n        if isinstance(value, list):\n            value = np.array(value)\n\n        _validate_data({key: value}, len(self))\n        self.data[key] = value\n\n    @property\n    def area(self) -> npt.NDArray[np.generic]:\n        \"\"\"\n        Calculate the area of each detection in the set of object detections.\n\n        Selection order:\n\n        1. If ``mask`` is set, return the area of each mask.\n        2. Else, if ``data[ORIENTED_BOX_COORDINATES]`` is set, return the area of\n           the rotated body (shoelace formula on the four corners).\n        3. Otherwise, return the axis-aligned box area (``box_area``).","sourceCodeStart":2778,"sourceCodeEnd":2814,"githubUrl":"https://github.com/roboflow/supervision/blob/7f254d9784d4c37e0f03cd89ddee164c8db099c0/src/supervision/detection/core.py#L2778-L2814","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\ndetections.set_data('camera_id', 3)  # TypeError\n\n# after\ndetections.set_data('camera_id', np.full(len(detections), 3))","handlingStrategy":"type-guard","validationCode":"import numpy as np\n\ndef set_data_safe(dets: sv.Detections, key: str, value) -> None:\n    if not isinstance(value, (np.ndarray, list)):\n        value = [value] * len(dets)\n    dets.set_data(key, value)\n\nset_data_safe(detections, 'camera_id', 3)","typeGuard":"def is_set_data_value(value) -> bool:\n    import numpy as np\n    return isinstance(value, (np.ndarray, list))","tryCatchPattern":null,"preventionTips":["Broadcast scalars to len(detections) lists yourself","Use Detections.metadata for whole-set state","Remember set_data is per-row, aligned with xyxy"],"tags":["set-data","type","detections","metadata"],"backgroundTag":null,"analyzedSha":"7f254d9784d4c37e0f03cd89ddee164c8db099c0","analyzedAt":"2026-08-15T05:13:01.950Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}