roboflow/supervision · error · ValueError

RLE size {(rle_h, rle_w)} must match image_shape {(img_h, im

Error message

RLE size {(rle_h, rle_w)} must match image_shape {(img_h, img_w)}.

What it means

Raised by CompactMask.from_coco_rle when an RLE's 'size' [height, width] does not equal the image_shape passed to the method. from_coco_rle expects full-image RLEs (not crop RLEs): each mask is decoded at image resolution and then cropped via the paired xyxy, so a size mismatch means the RLE cannot describe this image.

Source

Thrown at src/supervision/detection/compact_mask.py:824

        crop_shapes_list: list[tuple[int, int]] = []
        offsets_list: list[tuple[int, int]] = []

        for mask_idx, rle in enumerate(rles):
            if not isinstance(rle, Mapping):
                raise ValueError("Each RLE payload must be a mapping.")
            if "size" not in rle or "counts" not in rle:
                raise ValueError("Each RLE payload must contain 'size' and 'counts'.")

            try:
                # COCO standard: size=[height, width] (h,w order per pycocotools spec)
                rle_h, rle_w = rle["size"]
                rle_h = int(rle_h)
                rle_w = int(rle_w)
            except (TypeError, ValueError) as exc:
                raise ValueError("RLE size must be [height, width].") from exc

            if (rle_h, rle_w) != (img_h, img_w):
                raise ValueError(
                    f"RLE size {(rle_h, rle_w)} must match image_shape "
                    f"{(img_h, img_w)}."
                )

            counts = _coco_rle_counts_to_array(rle["counts"])
            if int(np.sum(counts, dtype=np.int64)) != img_h * img_w:
                raise ValueError(
                    "The sum of COCO RLE counts must match the image area."
                )

            x1, y1, x2, y2 = xyxy_arr[mask_idx]
            x1i, y1i, x2i, y2i = int(x1), int(y1), int(x2), int(y2)
            x1c = max(0, min(x1i, img_w - 1))
            y1c = max(0, min(y1i, img_h - 1))

            if (
                x2i < x1i
                or y2i < y1i

View on GitHub (pinned to 7f254d9784)

Solutions

  1. Match resolutions: either resize masks to the current image size before encoding, or pass image_shape equal to the annotation's size.
  2. Double-check ordering — both 'size' and image_shape are (height, width).
  3. If you only have crop RLEs, decode them yourself and use CompactMask.from_dense with the crop masks and their xyxy.

Example fix

# before — masks encoded at half resolution
cm = CompactMask.from_coco_rle(rles_half, xyxy, image_shape=(720, 1280))

# after — resize masks to image size first, then encode
masks_full = [cv2.resize(m, (1280, 720), interpolation=cv2.INTER_NEAREST) for m in masks_half]
rles = encode_all(masks_full)
cm = CompactMask.from_coco_rle(rles, xyxy, image_shape=(720, 1280))
Defensive patterns

Strategy: validation

Validate before calling

for r in rles:
    r_h, r_w = r["size"]
    assert (r_h, r_w) == tuple(image_shape), f"RLE size {(r_h, r_w)} != image_shape {tuple(image_shape)}"

Try / catch

try:
    cm = sv.CompactMask.from_coco_rle(rles, xyxy, image_shape=shape)
except ValueError as e:
    if "must match image_shape" in str(e):
        shape = tuple(rles[0]["size"])  # adopt annotation resolution
    else:
        raise

Prevention

When it happens

Trigger: Calling from_coco_rle with image_shape=(720, 1280) but an RLE whose size is [360, 640] (downscaled annotation); passing crop-sized RLEs; (h, w) vs (w, h) order swap between size and image_shape.

Common situations: Dataset annotated at a different resolution than the images being loaded; pycocotools encode run on resized masks; width/height order confusion (COCO size is [h, w] per pycocotools).

Related errors


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