{"record":{"id":"165349160287f8bc","repo":"roboflow/supervision","slug":"tracker-id-must-be-a-1d-np-ndarray-with-shape-exp","errorCode":null,"errorMessage":"tracker_id must be a 1D np.ndarray with shape {expected_shape}, but got shape {actual_shape}","messagePattern":"tracker_id must be a 1D np\\.ndarray with shape (.+?), but got shape (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/supervision/validators/__init__.py","lineNumber":176,"sourceCode":"\n\n@deprecated(  # type: ignore[untyped-decorator]\n    target=_validate_keypoint_confidence,\n    deprecated_in=\"0.27.0\",\n    remove_in=\"0.31.0\",\n)\ndef validate_keypoint_confidence(confidence: Any, n: int, m: int) -> None:\n    void(confidence, n, m)\n\n\ndef _validate_tracker_id(tracker_id: Any, n: int) -> None:\n    expected_shape = f\"({n},)\"\n    actual_shape = str(getattr(tracker_id, \"shape\", None))\n    is_valid = tracker_id is None or (\n        isinstance(tracker_id, np.ndarray) and tracker_id.shape == (n,)\n    )\n    if not is_valid:\n        raise ValueError(\n            f\"tracker_id must be a 1D np.ndarray with shape {expected_shape}, but got \"\n            f\"shape {actual_shape}\"\n        )\n\n\n@deprecated(  # type: ignore[untyped-decorator]\n    target=_validate_tracker_id,\n    deprecated_in=\"0.29.0\",\n    remove_in=\"0.32.0\",\n)\ndef validate_tracker_id(tracker_id: Any, n: int) -> None:\n    void(tracker_id, n)\n\n\ndef _validate_data(data: dict[str, Any], n: int) -> None:\n    for key, value in data.items():\n        if isinstance(value, list):\n            if len(value) != n:","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/roboflow/supervision/blob/7f254d9784d4c37e0f03cd89ddee164c8db099c0/src/supervision/validators/__init__.py#L158-L194","documentation":"Raised by supervision.validators._validate_tracker_id when tracker_id is supplied to Detections but is not None and not a 1D np.ndarray of shape (n,) aligned with xyxy. tracker_id carries the object ID assigned by a tracker (ByteTrack/BoT-SORT).","triggerScenarios":"Passing tracker_id as a Python list of ints, an array of shape (1, n), or an array longer/shorter than xyxy when building Detections manually.","commonSituations":"Feeding tracker output back into a reconstructed Detections object; keeping ids in a Python list across frames; desynchronizing ids after slicing/filtering detections without applying the same filter to ids.","solutions":["Convert to 1D NumPy array: tracker_id=np.asarray(ids, dtype=int).","Apply identical indexing to xyxy and tracker_id after any filtering: det = det[idx].","Prefer using tracker.update(dets) which returns Detections with a valid tracker_id already set.","Leave tracker_id=None for untracked detections."],"exampleFix":"# before\ndets = Detections(xyxy=boxes, tracker_id=[3, 7])  # list -> ValueError\n\n# after\ndets = Detections(xyxy=boxes, tracker_id=np.array([3, 7]))","handlingStrategy":"type-guard","validationCode":"n = len(xyxy)\ntracker_id = None if tracker_id is None else np.asarray(tracker_id).reshape(n)\ndets = Detections(xyxy=xyxy, tracker_id=tracker_id)","typeGuard":"def is_valid_tracker_id(tracker_id: Any, n: int) -> bool:\n    return tracker_id is None or (\n        isinstance(tracker_id, np.ndarray) and tracker_id.shape == (n,)\n    )","tryCatchPattern":null,"preventionTips":["Prefer tracker.update(detections) over manually wiring tracker_id.","Use det[idx] indexing to keep ids and boxes aligned.","np.asarray(ids).ravel() before manual construction."],"tags":["detections","tracking","validation","shape"],"backgroundTag":null,"analyzedSha":"7f254d9784d4c37e0f03cd89ddee164c8db099c0","analyzedAt":"2026-08-15T05:13:01.950Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}