roboflow/supervision · error · ValueError

visible must be a 2D np.ndarray with shape (n, m), but got s

Error message

visible must be a 2D np.ndarray with shape (n, m), but got shape {actual_shape}

What it means

Raised by supervision.validators._validate_visible (KeyPoints constructor path) when the visible argument is not None and is not a 2D np.ndarray. visible is a boolean mask of shape (n, m) marking which of the m keypoints are drawn/considered for each of the n objects.

Source

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

@deprecated(  # type: ignore[untyped-decorator]
    target=_validate_xy,
    deprecated_in="0.29.0",
    remove_in="0.32.0",
)
def validate_xy(xy: Any, n: int, m: int) -> None:
    void(xy, n, m)


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,

View on GitHub (pinned to 7f254d9784)

Solutions

  1. Convert to a 2D bool array: visible=np.asarray(mask, dtype=bool).reshape(n, m).
  2. Broadcast a single-object mask: np.tile(mask, (n, 1)).
  3. Leave visible=None to let KeyPoints infer visibility from coordinate data.

Example fix

# before
kp = KeyPoints(xy=xy, visible=[[True]*17])  # nested list -> ValueError

# after
kp = KeyPoints(xy=xy, visible=np.full((1, 17), True, dtype=bool))
Defensive patterns

Strategy: validation

Validate before calling

n, m = xy.shape[0], xy.shape[1]
visible = None if visible is None else np.asarray(visible, dtype=bool).reshape(n, m)
kp = KeyPoints(xy=xy, visible=visible)

Type guard

def is_valid_visible(visible: Any) -> bool:
    return visible is None or (
        isinstance(visible, np.ndarray) and visible.ndim == 2
    )

Prevention

When it happens

Trigger: Passing visible as a Python list of lists, a 1D array of length m, or a 3D array when constructing KeyPoints.

Common situations: Building the visibility mask from model output without np.asarray; reusing a per-object visibility vector for a batch of objects; confusing visible with confidence arrays.

Related errors


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