roboflow/supervision · error · ValueError

xyxy must be a 2D np.ndarray with shape {expected_shape}, bu

Error message

xyxy must be a 2D np.ndarray with shape {expected_shape}, but got shape {actual_shape}

What it means

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.

Source

Thrown at src/supervision/validators/__init__.py:22

from deprecate import deprecated, void  # type: ignore[import-untyped,unused-ignore]

from supervision.detection.compact_mask import CompactMask
from supervision.utils.internal import warn_deprecated


def _validate_xyxy(xyxy: Any) -> None:
    """Validate that xyxy is a 2D np.ndarray with shape (N, 4).

    ```pycon
    >>> _validate_xyxy(np.array([[0, 0, 1, 1], [1, 1, 2, 2]]))

    ```
    """
    expected_shape = "(_, 4)"
    actual_shape = str(getattr(xyxy, "shape", None))
    is_valid = isinstance(xyxy, np.ndarray) and xyxy.ndim == 2 and xyxy.shape[1] == 4
    if not is_valid:
        raise ValueError(
            f"xyxy must be a 2D np.ndarray with shape {expected_shape}, but got shape "
            f"{actual_shape}"
        )


@deprecated(  # type: ignore[untyped-decorator]
    target=_validate_xyxy,
    deprecated_in="0.29.0",
    remove_in="0.32.0",
)
def validate_xyxy(xyxy: Any) -> None:
    void(xyxy)


def _validate_mask(mask: Any, n: int) -> None:
    if mask is None:
        return

View on GitHub (pinned to 7f254d9784)

Solutions

  1. Convert and reshape: Detections(xyxy=boxes.reshape(-1, 4)) where boxes is a NumPy array.
  2. Convert xywh to xyxy with supervision.detection.utils.xywh_to_xyxy before constructing Detections.
  3. For a single box use np.array([[xmin, ymin, xmax, ymax]]) with explicit outer brackets.
  4. Prefer model connectors (Detections.from_ultralytics, etc.) which return correctly shaped arrays.

Example fix

# before
boxes = np.array([100, 100, 200, 200])
dets = Detections(xyxy=boxes)  # 1D -> ValueError

# after
boxes = np.array([[100, 100, 200, 200]])
dets = Detections(xyxy=boxes)
Defensive patterns

Strategy: type-guard

Validate before calling

xyxy = np.asarray(xyxy, dtype=np.float32).reshape(-1, 4)
dets = Detections(xyxy=xyxy)

Type guard

def is_valid_xyxy(xyxy: Any) -> bool:
    return (
        isinstance(xyxy, np.ndarray)
        and xyxy.ndim == 2
        and xyxy.shape[1] == 4
    )

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15). Data as JSON: /api/errors/0f1cd330f3f30fd7. Report an issue: GitHub.