roboflow/supervision · error · TypeError
mask must be boolean
Error message
mask must be boolean
What it means
The mask-cleanup helper (filter_small_components / keep-nearby-components style API in detection/utils/masks.py) is a TypeError raised when mask.dtype is not bool. Internally the mask is treated as a boolean bitmap for connected-component analysis; uint8/float arrays would change semantics (any nonzero counts), so the dtype is enforced strictly.
Source
Thrown at src/supervision/detection/utils/masks.py:452
[0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
```
The nearby 2x2 block at columns 6-7 is kept because its edge distance
is within 3 pixels. The distant block at columns 9-10 is removed.
""" # noqa E501 // docs
if mask.dtype != bool:
raise TypeError("mask must be boolean")
height, width = mask.shape
if not np.any(mask):
return cast(npt.NDArray[np.bool_], mask.copy())
image = cast(npt.NDArray[np.uint8], mask.astype(np.uint8))
components = cv2.connectedComponentsWithStats(image, connectivity=connectivity)
num_labels = int(components[0])
labels = cast(npt.NDArray[np.int32], components[1])
stats = cast(npt.NDArray[np.int32], components[2])
centroids = cast(npt.NDArray[np.float64], components[3])
if num_labels <= 1:
return cast(npt.NDArray[np.bool_], mask.copy())
areas = stats[1:, cv2.CC_STAT_AREA]
max_area = int(areas.max())
candidates = 1 + np.flatnonzero(areas == max_area)View on GitHub (pinned to 7f254d9784)
Solutions
- Convert before calling: mask.astype(bool).
- Normalize masks once at the boundary of your pipeline (right after model inference) to bool.
- For 0/255 images, threshold: mask = img > 127.
Example fix
# before cleaned = filter_non_zero_mask_areas(mask=raw_uint8_mask, ...) # after cleaned = filter_non_zero_mask_areas(mask=raw_uint8_mask.astype(bool), ...)
Defensive patterns
Strategy: type-guard
Validate before calling
if mask.dtype != np.bool_:
mask = mask.astype(bool) Type guard
def is_bool_mask(mask: npt.NDArray) -> bool:
return mask.dtype == np.bool_ Try / catch
try:
result = filter_non_zero_mask_areas(mask=mask, ...)
except TypeError as e:
raise TypeError(f"Mask dtype {mask.dtype} not supported: {e}") from e Prevention
- Convert uint8/float masks to bool once, right after model inference.
- Use mask > 0 (or > 127 for 0/255 images) instead of astype for thresholds.
- Standardize on boolean masks across your whole supervision pipeline.
When it happens
Trigger: Passing a 0/255 uint8 mask loaded from cv2.imread or a model's logits/float array without converting: calling the cleanup function with mask.astype(np.uint8) output straight from an inference pipeline.
Common situations: Masks from SAM/YOLO seg branches stored as uint8; masks saved/loaded as PNG images; mixing supervision boolean-mask APIs with OpenCV convention (0/255).
Related errors
- Incorrect connectivity value. Possible connectivity values:
- All sigma values must be positive
- color length ({len(color_seq)}) must match sigma length ({le
- Number of labels ({len(resolved)}) must match number of key
- labels is a dict but class_id is None; KeyPoints must have c
AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15).
Data as JSON: /api/errors/3a412d99cd9156d5.
Report an issue: GitHub.