{"record":{"id":"de46f820519e8810","repo":"roboflow/supervision","slug":"xyxyxyxy-must-have-shape-n-4-2-got-xyxyxyxy","errorCode":null,"errorMessage":"xyxyxyxy must have shape (N, 4, 2); got {xyxyxyxy.shape}","messagePattern":"xyxyxyxy must have shape \\(N, 4, 2\\); got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/supervision/detection/utils/boxes.py","lineNumber":311,"sourceCode":"        ValueError: If `xyxyxyxy` does not have shape `(N, 4, 2)`.\n\n    Examples:\n        ```pycon\n        >>> import numpy as np\n        >>> import supervision as sv\n        >>> corners = np.array([\n        ...     [[0, 0], [10, 0], [10, 5], [0, 5]],\n        ...     [[5, 5], [15, 5], [15, 10], [5, 10]],\n        ... ], dtype=np.float32)\n        >>> sv.xyxyxyxy_to_xyxy(corners)\n        array([[ 0.,  0., 10.,  5.],\n               [ 5.,  5., 15., 10.]], dtype=float32)\n\n        ```\n    \"\"\"\n    xyxyxyxy = cast(npt.NDArray[np.number], np.asarray(xyxyxyxy))\n    if xyxyxyxy.ndim != 3 or xyxyxyxy.shape[-2:] != (4, 2):\n        raise ValueError(f\"xyxyxyxy must have shape (N, 4, 2); got {xyxyxyxy.shape}\")\n    x_min = xyxyxyxy[..., 0].min(axis=-1)\n    y_min = xyxyxyxy[..., 1].min(axis=-1)\n    x_max = xyxyxyxy[..., 0].max(axis=-1)\n    y_max = xyxyxyxy[..., 1].max(axis=-1)\n    return cast(npt.NDArray[np.number], np.stack([x_min, y_min, x_max, y_max], axis=-1))\n\n\n# Anchor position -> (sx, sy) offset from the box center, in units of the box\n# half-width and half-height. Image coordinates, so +y points down.\n_ANCHOR_OFFSETS: dict[Position, tuple[float, float]] = {\n    Position.CENTER: (0.0, 0.0),\n    Position.CENTER_LEFT: (-1.0, 0.0),\n    Position.CENTER_RIGHT: (1.0, 0.0),\n    Position.TOP_CENTER: (0.0, -1.0),\n    Position.BOTTOM_CENTER: (0.0, 1.0),\n    Position.TOP_LEFT: (-1.0, -1.0),\n    Position.TOP_RIGHT: (1.0, -1.0),\n    Position.BOTTOM_LEFT: (-1.0, 1.0),","sourceCodeStart":293,"sourceCodeEnd":329,"githubUrl":"https://github.com/roboflow/supervision/blob/7f254d9784d4c37e0f03cd89ddee164c8db099c0/src/supervision/detection/utils/boxes.py#L293-L329","documentation":"Raised by xyxyxyxy_to_xyxy when the input oriented-box corner array is not shaped (N, 4, 2). The conversion takes per-box min/max over the corner axis, which only makes sense when every box contributes exactly 4 (x, y) pairs; any other layout would produce wrong axis-aligned bounds.","triggerScenarios":"Passing a single un-batched box of shape (4, 2); passing an (N, 8) or (N, 4, 4) flattened layout; passing a ragged Python list whose np.asarray result is object-dtype or 2-D.","commonSituations":"Models that emit OBB corners flattened as 8 numbers per box (common in YOLO-OBB outputs before reshaping); forgetting the batch dimension for one box; mixing up the xyxy (N, 4) and xyxyxyxy (N, 4, 2) conventions.","solutions":["Reshape flattened 8-number boxes: corners = flat.reshape(-1, 4, 2).","Add a batch axis for a single box: corners = box[np.newaxis].","If you have axis-aligned xyxy boxes, you do not need this function — use the array as is."],"exampleFix":"# before\ncorners = model_output.reshape(-1, 8)\nsv.xyxyxyxy_to_xyxy(corners)  # ValueError\n\n# after\ncorners = model_output.reshape(-1, 4, 2)\nsv.xyxyxyxy_to_xyxy(corners)","handlingStrategy":"type-guard","validationCode":"import numpy as np\n\ndef to_xyxyxyxy(a) -> np.ndarray:\n    a = np.asarray(a)\n    if a.ndim == 2 and a.shape[-1] == 8:\n        a = a.reshape(-1, 4, 2)\n    if a.ndim == 2 and a.shape == (4, 2):\n        a = a[np.newaxis]\n    assert a.ndim == 3 and a.shape[-2:] == (4, 2), f'bad shape {a.shape}'\n    return a\n\nxyxy = sv.xyxyxyxy_to_xyxy(to_xyxyxyxy(corners))","typeGuard":"def is_xyxyxyxy(a) -> bool:\n    a = np.asarray(a)\n    return a.ndim == 3 and a.shape[-2:] == (4, 2)","tryCatchPattern":null,"preventionTips":["Standardize on (N, 4, 2) for all oriented-box arrays in your codebase; reshape once at ingestion.","Do not pass xyxy (N, 4) arrays to oriented-box converters."],"tags":["oriented-bounding-box","coordinate-conversion","numpy","shape-validation","valueerror"],"backgroundTag":null,"analyzedSha":"7f254d9784d4c37e0f03cd89ddee164c8db099c0","analyzedAt":"2026-08-15T05:13:01.950Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}