roboflow/supervision · error · ValueError
visible second dimension must be {m}, but got shape {actual_
Error message
visible second dimension must be {m}, but got shape {actual_shape} What it means
Raised by supervision.validators._validate_visible when visible's second dimension does not equal m, the number of keypoints per object expected from xy. The check runs only when n > 0, because with zero objects m cannot be cross-validated.
Source
Thrown at src/supervision/validators/__init__.py:254
def _validate_visible(visible: Any, n: int, m: int) -> None:
"""Validate per-keypoint visibility mask.
Expects a 2D bool ``np.ndarray`` with shape ``(n, m)``.
"""
if visible is None:
return
actual_shape = str(getattr(visible, "shape", None))
if not isinstance(visible, np.ndarray) or visible.ndim != 2:
raise ValueError(
"visible must be a 2D np.ndarray with shape (n, m), but "
f"got shape {actual_shape}"
)
if visible.shape[0] != n:
raise ValueError(
f"visible first dimension must be {n}, but got shape {actual_shape}"
)
if n > 0 and visible.shape[1] != m:
raise ValueError(
f"visible second dimension must be {m}, but got shape {actual_shape}"
)
def _validate_detections_fields(
xyxy: Any,
mask: Any,
class_id: Any,
confidence: Any,
tracker_id: Any,
data: dict[str, Any],
) -> None:
_validate_xyxy(xyxy)
n = len(xyxy)
_validate_mask(mask, n)
_validate_class_id(class_id, n)
_validate_confidence(confidence, n)
_validate_tracker_id(tracker_id, n)View on GitHub (pinned to 7f254d9784)
Solutions
- Derive m from xy: m = xy.shape[1], and build visible with exactly m columns.
- Trim/pad the mask to match: visible = visible[:, :xy.shape[1]].
- Use None for visible when unsure, and let KeyPoints infer visibility.
Example fix
# before kp = KeyPoints(xy=xy, visible=vis_13) # xy has 17 points # after kp = KeyPoints(xy=xy, visible=vis_13[:, :xy.shape[1]]) # or rebuild with 17 cols
Defensive patterns
Strategy: validation
Validate before calling
m = xy.shape[1] visible = np.asarray(visible, dtype=bool)[:, :m] kp = KeyPoints(xy=xy, visible=visible)
Type guard
def visible_cols_match(visible: np.ndarray, xy: np.ndarray) -> bool:
return visible.ndim == 2 and visible.shape[1] == xy.shape[1] Prevention
- Pin one keypoint schema per pipeline; document m.
- Slice keypoint columns and visibility columns together.
- Derive m from xy.shape[1] instead of hardcoding.
When it happens
Trigger: Constructing KeyPoints with xy of shape (1, 17, 2) but a visible mask of shape (1, 13) — e.g. a COCO-17 model with a 13-point visibility vector.
Common situations: Mixing keypoint schemas (COCO 17 vs. MPII 16 vs. custom 13); hardcoding m from a different pose model; keeping a stale visibility mask after switching skeletons.
Related errors
- visible must be a 2D np.ndarray with shape (n, m), but got s
- visible first dimension must be {n}, but got shape {actual_s
- xy must be a 3D np.ndarray with shape {expected_shape}, but
- keypoint_confidence must be a 2D np.ndarray with shape (n, m
- keypoint_confidence first dimension must be {n}, but got sha
AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15).
Data as JSON: /api/errors/8c523b958db15da8.
Report an issue: GitHub.