roboflow/supervision · error · ValueError
xyxyxyxy must have shape (N, 4, 2); got {corners.shape}
Error message
xyxyxyxy must have shape (N, 4, 2); got {corners.shape} What it means
Raised by the private helper _oriented_box_anchors in boxes.py when the corner array is not shaped (N, 4, 2). The helper computes box centers and half-side vectors by indexing corners[:, 1], corners[:, 2], etc., so exactly 4 corner points per box are required. Note the message names the parameter 'xyxyxyxy' even though the local variable is 'corners' — same requirement either way.
Source
Thrown at src/supervision/detection/utils/boxes.py:385
The anchor always lies on the box; the effect is cosmetic for static
images but visible on rotating objects in video.
Examples:
```pycon
>>> import numpy as np
>>> from supervision.detection.utils.boxes import _oriented_box_anchors
>>> from supervision.geometry.core import Position
>>> corners = np.array(
... [[[0, 0], [10, 0], [10, 4], [0, 4]]], dtype=np.float32
... )
>>> _oriented_box_anchors(corners, Position.BOTTOM_CENTER)
array([[5., 4.]])
```
"""
corners = np.asarray(xyxyxyxy, dtype=np.float64)
if corners.ndim != 3 or corners.shape[-2:] != (4, 2):
raise ValueError(f"xyxyxyxy must have shape (N, 4, 2); got {corners.shape}")
if anchor not in _ANCHOR_OFFSETS:
raise ValueError(f"{anchor} is not supported.")
sx, sy = _ANCHOR_OFFSETS[anchor]
center = corners.mean(axis=1)
# Two perpendicular half-side vectors per box.
half_side_a = (corners[:, 1] - corners[:, 0]) / 2
half_side_b = (corners[:, 2] - corners[:, 1]) / 2
# Map each box's own sides onto the image axes: the side more aligned with
# the x-axis plays the role of width, the other of height. This makes the
# offsets collapse to the axis-aligned frame when the box is not rotated.
is_width = np.abs(half_side_a[:, 0]) >= np.abs(half_side_b[:, 0])
width = np.where(is_width[:, None], half_side_a, half_side_b)
height = np.where(is_width[:, None], half_side_b, half_side_a)
# Point width toward +x and height toward +y so the offset signs are stable.
width = np.where((width[:, 0] < 0)[:, None], -width, width)
height = np.where((height[:, 1] < 0)[:, None], -height, height)View on GitHub (pinned to 7f254d9784)
Solutions
- Reshape input to (N, 4, 2): flat.reshape(-1, 4, 2) or box[np.newaxis] for a single box.
- If you hit this via an annotator, fix the ORIENTED_BOX_COORDINATES data field attached to your Detections so it has shape (N, 4, 2).
- Prefer the public API path (annotators) instead of calling the underscore-prefixed helper directly.
Example fix
# before anchors = _oriented_box_anchors(box_4x2, Position.BOTTOM_CENTER) # ValueError # after anchors = _oriented_box_anchors(box_4x2[np.newaxis], Position.BOTTOM_CENTER)
Defensive patterns
Strategy: type-guard
Validate before calling
corners = np.asarray(corners, dtype=np.float64).reshape(-1, 4, 2) anchors = _oriented_box_anchors(corners, position)
Type guard
def is_xyxyxyxy(a) -> bool:
a = np.asarray(a)
return a.ndim == 3 and a.shape[-2:] == (4, 2) Prevention
- Avoid the private underscore helper; go through public annotators.
- Ensure Detections.data[ORIENTED_BOX_COORDINATES] always has shape (N, 4, 2).
When it happens
Trigger: Calling _oriented_box_anchors (directly, or indirectly through an annotator that places labels on rotated boxes) with an un-batched (4, 2) array, an (N, 8) flattened array, or an array with the wrong corner count.
Common situations: Custom annotation code that holds OBB corners in a non-standard layout; downstream code reshaping model output incorrectly before annotation; usually reached via BoxAnnotator/LabelAnnotator with oriented detections rather than called directly.
Related errors
- corners must have shape (N, 4, 2); got {corners.shape}
- xyxyxyxy must have shape (N, 4, 2); got {xyxyxyxy.shape}
- {anchor} is not supported.
- Confusion matrix must have shape (..., 3), got {confusion_ma
- Value must be a np.ndarray or a list
AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15).
Data as JSON: /api/errors/40ff817f784b929f.
Report an issue: GitHub.