roboflow/supervision · error · ValueError
Bounding boxes must be shaped (N, 4)
Error message
Bounding boxes must be shaped (N, 4)
What it means
Raised by get_bbox_size_category() when the input bounding-box array is not 2-D with exactly 4 columns (xyxy format). The function computes width*height per row to bucket boxes into SMALL/MEDIUM/LARGE, so a malformed shape would corrupt the per-box area vector. It validates shape before any arithmetic.
Source
Thrown at src/supervision/metrics/utils/object_size.py:117
the enum values of ObjectSizeCategory. Shaped (N,).
Example:
```pycon
>>> import numpy as np
>>> from supervision.metrics.utils.object_size import get_bbox_size_category
>>> xyxy = np.array([
... [0, 0, 31, 31], # 961 (Small)
... [0, 0, 32, 32], # 1024 (Medium)
... [0, 0, 95, 95], # 9025 (Medium)
... [0, 0, 96, 96] # 9216 (Large)
... ])
>>> get_bbox_size_category(xyxy)
array([1, 2, 2, 3])
```
"""
if len(xyxy.shape) != 2 or xyxy.shape[1] != 4:
raise ValueError("Bounding boxes must be shaped (N, 4)")
width = xyxy[:, 2] - xyxy[:, 0]
height = xyxy[:, 3] - xyxy[:, 1]
areas = width * height
result = np.full(areas.shape, ObjectSizeCategory.ANY.value)
SM, LG = SIZE_THRESHOLDS
result[areas < SM] = ObjectSizeCategory.SMALL.value
result[(areas >= SM) & (areas < LG)] = ObjectSizeCategory.MEDIUM.value
result[areas >= LG] = ObjectSizeCategory.LARGE.value
return result
def get_area_size_category(
areas: npt.NDArray[np.number],
) -> npt.NDArray[np.int_]:
"""Get object size categories from per-detection pixel areas.
View on GitHub (pinned to 7f254d9784)
Solutions
- Reshape input to (N, 4): np.asarray(boxes).reshape(-1, 4) when it is a flat list of boxes
- If you have oriented boxes, use get_obb_size_category instead
- Add a shape assert in your pipeline: assert boxes.ndim == 2 and boxes.shape[1] == 4
Example fix
# before size = get_bbox_size_category(np.array([0, 0, 31, 31])) # 1-D # after size = get_bbox_size_category(np.array([[0, 0, 31, 31]])) # (1, 4)
Defensive patterns
Strategy: validation
Validate before calling
boxes = np.asarray(boxes)
if boxes.ndim != 2 or boxes.shape[1] != 4:
boxes = boxes.reshape(-1, 4)
cats = get_bbox_size_category(boxes) Type guard
import numpy as np
def is_valid_xyxy(arr: np.ndarray) -> bool:
"""True when arr is (N, 4) suitable for bbox size categorization."""
return arr.ndim == 2 and arr.shape[1] == 4 Try / catch
try:
cats = get_bbox_size_category(boxes)
except ValueError as e:
if 'shaped (N, 4)' in str(e):
cats = get_bbox_size_category(boxes.reshape(-1, 4))
else:
raise Prevention
- Always wrap single boxes in a list: np.array([[x1, y1, x2, y2]])
- Keep OBB corners out of xyxy paths; convert formats explicitly
When it happens
Trigger: Calling get_bbox_size_category with a (N,5) array, a flat (4,) vector, a (N,4,2) OBB array, or an empty (0,) array.
Common situations: Passing xyxyxyxy (oriented box) coordinates by mistake; passing a single box [x1,y1,x2,y2] without wrapping in a 2-D array; slicing errors that drop a dimension; passing mask or polygon data.
Related errors
- Areas must be shaped (N,)
- Confusion matrix must have shape (..., 3), got {confusion_ma
- Oriented bounding boxes must be shaped (N, 4, 2)
- Masks must be shaped (N, H, W)
- Value must be a np.ndarray or a list
AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15).
Data as JSON: /api/errors/fb334ca397c38ac1.
Report an issue: GitHub.