{"record":{"id":"0f1cd330f3f30fd7","repo":"roboflow/supervision","slug":"xyxy-must-be-a-2d-np-ndarray-with-shape-expected","errorCode":null,"errorMessage":"xyxy must be a 2D np.ndarray with shape {expected_shape}, but got shape {actual_shape}","messagePattern":"xyxy must be a 2D np\\.ndarray with shape (.+?), but got shape (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/supervision/validators/__init__.py","lineNumber":22,"sourceCode":"from deprecate import deprecated, void  # type: ignore[import-untyped,unused-ignore]\n\nfrom supervision.detection.compact_mask import CompactMask\nfrom supervision.utils.internal import warn_deprecated\n\n\ndef _validate_xyxy(xyxy: Any) -> None:\n    \"\"\"Validate that xyxy is a 2D np.ndarray with shape (N, 4).\n\n    ```pycon\n    >>> _validate_xyxy(np.array([[0, 0, 1, 1], [1, 1, 2, 2]]))\n\n    ```\n    \"\"\"\n    expected_shape = \"(_, 4)\"\n    actual_shape = str(getattr(xyxy, \"shape\", None))\n    is_valid = isinstance(xyxy, np.ndarray) and xyxy.ndim == 2 and xyxy.shape[1] == 4\n    if not is_valid:\n        raise ValueError(\n            f\"xyxy must be a 2D np.ndarray with shape {expected_shape}, but got shape \"\n            f\"{actual_shape}\"\n        )\n\n\n@deprecated(  # type: ignore[untyped-decorator]\n    target=_validate_xyxy,\n    deprecated_in=\"0.29.0\",\n    remove_in=\"0.32.0\",\n)\ndef validate_xyxy(xyxy: Any) -> None:\n    void(xyxy)\n\n\ndef _validate_mask(mask: Any, n: int) -> None:\n    if mask is None:\n        return\n","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/roboflow/supervision/blob/7f254d9784d4c37e0f03cd89ddee164c8db099c0/src/supervision/validators/__init__.py#L4-L40","documentation":"Raised by supervision.validators._validate_xyxy when the xyxy argument to Detections is not a 2D NumPy array with exactly 4 columns. xyxy is the canonical box container for Detections and must have shape (N, 4) as (xmin, ymin, xmax, ymax) per row.","triggerScenarios":"Constructing Detections(xyxy=np.array([0, 0, 1, 1])) (1D), Detections(xyxy=np.array([[0, 0, 1]])) (3 columns), or passing a Python list/None instead of np.ndarray.","commonSituations":"Forgetting np.array()/np.asarray() on raw model output; hand-building Detections from a single box instead of a batch; passing xywh (4 values but wrong order/semantics is fine shape-wise, passing (N, 5) with confidence appended is not); slicing arrays incorrectly so they collapse to 1D.","solutions":["Convert and reshape: Detections(xyxy=boxes.reshape(-1, 4)) where boxes is a NumPy array.","Convert xywh to xyxy with supervision.detection.utils.xywh_to_xyxy before constructing Detections.","For a single box use np.array([[xmin, ymin, xmax, ymax]]) with explicit outer brackets.","Prefer model connectors (Detections.from_ultralytics, etc.) which return correctly shaped arrays."],"exampleFix":"# before\nboxes = np.array([100, 100, 200, 200])\ndets = Detections(xyxy=boxes)  # 1D -> ValueError\n\n# after\nboxes = np.array([[100, 100, 200, 200]])\ndets = Detections(xyxy=boxes)","handlingStrategy":"type-guard","validationCode":"xyxy = np.asarray(xyxy, dtype=np.float32).reshape(-1, 4)\ndets = Detections(xyxy=xyxy)","typeGuard":"def is_valid_xyxy(xyxy: Any) -> bool:\n    return (\n        isinstance(xyxy, np.ndarray)\n        and xyxy.ndim == 2\n        and xyxy.shape[1] == 4\n    )","tryCatchPattern":null,"preventionTips":["Wrap raw model output with np.asarray(...).reshape(-1, 4) before Detections.","Use xywh_to_xyxy when the source format is center-based.","Prefer built-in from_* connectors over manual construction."],"tags":["detections","validation","shape","numpy"],"backgroundTag":null,"analyzedSha":"7f254d9784d4c37e0f03cd89ddee164c8db099c0","analyzedAt":"2026-08-15T05:13:01.950Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}