roboflow/supervision · error · ValueError
Each RLE payload must be a mapping.
Error message
Each RLE payload must be a mapping.
What it means
Raised by CompactMask.from_coco_rle when an element of the rles sequence is not a Mapping (dict-like). Each RLE payload must expose 'size' and 'counts' keys, which requires mapping access; lists, tuples, strings, or None are rejected with this error before any key lookup.
Source
Thrown at src/supervision/detection/compact_mask.py:811
raise ValueError(
"xyxy must have shape (N, 4), where N matches the number of RLEs."
)
if len(rles) == 0:
return cls(
[],
np.empty((0, 2), dtype=np.int32),
np.empty((0, 2), dtype=np.int32),
(img_h, img_w),
)
crop_rles: list[npt.NDArray[np.int32]] = []
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"])View on GitHub (pinned to 7f254d9784)
Solutions
- Normalize each payload to a dict with the two keys: {'size': [h, w], 'counts': counts}.
- Filter out None/empty segmentation entries before building the list.
- If you have parallel arrays of sizes and counts, zip them into dicts before the call.
Example fix
# before
rles = [ann["segmentation"]["counts"] for ann in anns]
# after
rles = [{"size": ann["segmentation"]["size"],
"counts": ann["segmentation"]["counts"]} for ann in anns] Defensive patterns
Strategy: type-guard
Validate before calling
from collections.abc import Mapping
assert all(isinstance(r, Mapping) and {"size", "counts"} <= r.keys() for r in rles), "bad RLE payload" Type guard
from collections.abc import Mapping
def is_coco_rle_payload(obj) -> bool:
return isinstance(obj, Mapping) and "size" in obj and "counts" in obj Try / catch
try:
cm = sv.CompactMask.from_coco_rle(rles, xyxy, image_shape=shape)
except ValueError as e:
if "must be a mapping" in str(e):
rles = [r if isinstance(r, dict) else {"size": s, "counts": r} for r, s in zip(rles, sizes)]
else:
raise Prevention
- Always materialize payloads as dicts with exactly 'size' and 'counts'.
- Filter None segmentation entries when walking COCO annotations.
- Zip parallel size/counts arrays into dicts at the boundary of your code.
When it happens
Trigger: Passing rles = [[4, 4], ...] (positional lists), rles = [None], rles = ['01b...'] (bare compressed strings), or a numpy structured array instead of [{'size': ..., 'counts': ...}, ...].
Common situations: Grabbing ann['segmentation']['counts'] strings from COCO JSON and zipping them into lists instead of rebuilding dicts; passing pycocotools RLE objects (which are dicts and fine) mixed with raw strings; None placeholders for missing masks.
Related errors
- Invalid COCO RLE counts.
- Each RLE payload must contain 'size' and 'counts'.
- RLE size must be [height, width].
- COCO RLE counts must be one-dimensional.
- COCO RLE counts cannot be empty.
AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15).
Data as JSON: /api/errors/f86fd29a8f2fa37e.
Report an issue: GitHub.