roboflow/supervision · error · ValueError

SAM segmentations must all be dense arrays or COCO RLE dicti

Error message

SAM segmentations must all be dense arrays or COCO RLE dictionaries.

What it means

Detections.from_sam accepts SAM outputs whose 'segmentation' entries are either all dense boolean np.ndarrays (SamAutomaticMaskGenerator default) or all COCO RLE dicts (from mask generators configured with output_mode='coco_rle'). The np.stack/rle_to_mask logic cannot handle a mixed or foreign-typed list, so anything else raises this ValueError.

Source

Thrown at src/supervision/detection/core.py:848

        if all(isinstance(segmentation, np.ndarray) for segmentation in segmentations):
            mask = np.stack(segmentations, axis=0)
        elif all(isinstance(segmentation, dict) for segmentation in segmentations):
            image_height, image_width = cast(
                tuple[int, int], tuple(int(v) for v in first_segmentation["size"])
            )
            mask = np.stack(
                [
                    rle_to_mask(
                        segmentation["counts"],
                        (image_width, image_height),
                    )
                    for segmentation in segmentations
                ],
                axis=0,
            )
        else:
            raise ValueError(
                "SAM segmentations must all be dense arrays or COCO RLE dictionaries."
            )

        xyxy = xywh_to_xyxy(xywh=xywh)
        return cls(xyxy=xyxy, mask=mask)

    @classmethod
    def from_sam3(
        cls, sam3_result: dict[str, Any] | Any, resolution_wh: tuple[int, int]
    ) -> Detections:
        """
        Creates a Detections instance from
        [SAM 3](https://github.com/facebookresearch/sam3) inference result.
        Supports both PVS and PCS SAM3 segmentation formats.

        Args:
            sam3_result: The output result from SAM 3 inference, either
                Sam3PromptResult from inference package or dict containing

View on GitHub (pinned to 7f254d9784)

Solutions

  1. Normalize every segmentation to dense np.ndarray (mask dtype bool/uint8) before calling from_sam: np.asarray(seg, dtype=bool) or decode RLE entries with supervision's rle_to_mask.
  2. If using SamAutomaticMaskGenerator, set a single output_mode ('binary_mask' or 'coco_rle') and don't mix runs.
  3. After JSON round-trips, convert nested lists back: [np.asarray(s, dtype=bool) for s in segmentations].

Example fix

# before
# segs is a mix of np.ndarray and RLE dicts after merging two SAM runs
detections = sv.Detections.from_sam(sam_result)  # ValueError

# after
for item in sam_result:
    seg = item['segmentation']
    if isinstance(seg, dict):
        from supervision.detection.utils import rle_to_mask
        h, w = seg['size']
        item['segmentation'] = rle_to_mask(seg['counts'], (w, h))
detections = sv.Detections.from_sam(sam_result)
Defensive patterns

Strategy: type-guard

Validate before calling

import numpy as np

def normalize_sam_result(sam_result: list[dict]) -> list[dict]:
    for item in sam_result:
        seg = item['segmentation']
        if isinstance(seg, dict):
            from supervision.detection.utils import rle_to_mask
            h, w = seg['size']
            item['segmentation'] = rle_to_mask(seg['counts'], (w, h))
        elif not isinstance(seg, np.ndarray):
            item['segmentation'] = np.asarray(seg, dtype=bool)
    return sam_result

detections = sv.Detections.from_sam(normalize_sam_result(sam_result))

Type guard

def sam_result_uniform(sam_result: list) -> bool:
    segs = [m['segmentation'] for m in sam_result]
    types = {type(s) for s in segs}
    return types <= {np.ndarray} or types <= {dict}

Try / catch

try:
    detections = sv.Detections.from_sam(sam_result)
except ValueError as e:
    if 'dense arrays or COCO RLE' in str(e):
        detections = sv.Detections.from_sam(normalize_sam_result(sam_result))
    else:
        raise

Prevention

When it happens

Trigger: Passing a sam_result list where some items have np.ndarray 'segmentation' and others have dict RLE 'segmentation'; segmentations stored as torch.Tensor, lists, pycocotools RLE objects, or any other type after serialization/conversion; concatenating outputs from two SAM runs with different output modes.

Common situations: Saving SAM results to JSON (arrays become nested lists, RLE dicts survive) then reloading and mixing with fresh results; converting masks to torch tensors for a GPU step then calling from_sam on the converted list; merging binary_mask and coco_rle outputs.

Related errors


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