{"record":{"id":"6396511b5a3aeef4","repo":"roboflow/supervision","slug":"visible-first-dimension-must-be-n-but-got-shape","errorCode":null,"errorMessage":"visible first dimension must be {n}, but got shape {actual_shape}","messagePattern":"visible first dimension must be (.+?), but got shape (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/supervision/validators/__init__.py","lineNumber":250,"sourceCode":"def validate_xy(xy: Any, n: int, m: int) -> None:\n    void(xy, n, m)\n\n\ndef _validate_visible(visible: Any, n: int, m: int) -> None:\n    \"\"\"Validate per-keypoint visibility mask.\n\n    Expects a 2D bool ``np.ndarray`` with shape ``(n, m)``.\n    \"\"\"\n    if visible is None:\n        return\n    actual_shape = str(getattr(visible, \"shape\", None))\n    if not isinstance(visible, np.ndarray) or visible.ndim != 2:\n        raise ValueError(\n            \"visible must be a 2D np.ndarray with shape (n, m), but \"\n            f\"got shape {actual_shape}\"\n        )\n    if visible.shape[0] != n:\n        raise ValueError(\n            f\"visible first dimension must be {n}, but got shape {actual_shape}\"\n        )\n    if n > 0 and visible.shape[1] != m:\n        raise ValueError(\n            f\"visible second dimension must be {m}, but got shape {actual_shape}\"\n        )\n\n\ndef _validate_detections_fields(\n    xyxy: Any,\n    mask: Any,\n    class_id: Any,\n    confidence: Any,\n    tracker_id: Any,\n    data: dict[str, Any],\n) -> None:\n    _validate_xyxy(xyxy)\n    n = len(xyxy)","sourceCodeStart":232,"sourceCodeEnd":268,"githubUrl":"https://github.com/roboflow/supervision/blob/7f254d9784d4c37e0f03cd89ddee164c8db099c0/src/supervision/validators/__init__.py#L232-L268","documentation":"Raised by supervision.validators._validate_visible when visible is a 2D array but its first dimension does not equal n, the number of key-point objects in xy. Every object row must have a corresponding visibility row.","triggerScenarios":"Constructing KeyPoints with xy of shape (3, 17, 2) but visible of shape (2, 17) or (1, 17).","commonSituations":"Using one visibility mask for a multi-person frame; filtering xy objects without filtering visible rows in sync; off-by-one after dropping an object from xy.","solutions":["Rebuild or slice visible so visible.shape[0] == xy.shape[0].","Apply the same object-index mask to both: xy = xy[idx]; visible = visible[idx].","Tile a shared mask: visible = np.tile(single_mask, (xy.shape[0], 1))."],"exampleFix":"# before\nkp = KeyPoints(xy=xy, visible=vis)  # xy:(3,17,2), vis:(1,17)\n\n# after\nkp = KeyPoints(xy=xy, visible=np.tile(vis, (xy.shape[0], 1)))","handlingStrategy":"validation","validationCode":"n = xy.shape[0]\nvisible = np.asarray(visible, dtype=bool)\nassert visible.shape[0] == n, f\"visible rows {visible.shape[0]} != objects {n}\"\nkp = KeyPoints(xy=xy, visible=visible)","typeGuard":"def visible_rows_match(visible: np.ndarray, xy: np.ndarray) -> bool:\n    return visible.ndim == 2 and visible.shape[0] == xy.shape[0]","tryCatchPattern":null,"preventionTips":["Derive n from xy.shape[0] and size visible accordingly.","Filter visible with the same object indices as xy.","Tile single-object masks explicitly with np.tile."],"tags":["keypoints","validation","shape","mask"],"backgroundTag":null,"analyzedSha":"7f254d9784d4c37e0f03cd89ddee164c8db099c0","analyzedAt":"2026-08-15T05:13:01.950Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}