roboflow/supervision · error · ValueError
COCO RLE counts must be non-negative.
Error message
COCO RLE counts must be non-negative.
What it means
Raised when any element of the COCO RLE counts array is negative. RLE counts encode run lengths of alternating background/foreground pixels and are, by definition, non-negative. A negative value indicates malformed or corrupt RLE data, and the parser rejects it before attempting to reconstruct the mask.
Source
Thrown at src/supervision/detection/compact_mask.py:413
# narrowing. A direct int32 cast wraps silently on some numpy versions
# and raises on others; this makes overflow detection deterministic.
counts_arr64 = np.asarray(counts, dtype=np.int64)
int32_info = np.iinfo(np.int32)
if counts_arr64.size and (
counts_arr64.max() > int32_info.max
or counts_arr64.min() < int32_info.min
):
raise ValueError("COCO RLE counts exceed int32 range.")
counts_arr = counts_arr64.astype(np.int32)
except (TypeError, ValueError, OverflowError) as exc:
raise ValueError("Invalid COCO RLE counts.") from exc
if counts_arr.ndim != 1:
raise ValueError("COCO RLE counts must be one-dimensional.")
if counts_arr.size == 0:
raise ValueError("COCO RLE counts cannot be empty.")
if np.any(counts_arr < 0):
raise ValueError("COCO RLE counts must be non-negative.")
return counts_arr
def _rle_resize(
rle: npt.NDArray[np.int32],
crop_h: int,
crop_w: int,
new_crop_h: int,
new_crop_w: int,
) -> npt.NDArray[np.int32]:
"""Resize an F-order RLE-encoded crop via nearest-neighbour resampling.
Manipulates run lengths directly without decoding to a full 2D boolean
array. Delegates to :func:`_rle_split_cols`, :func:`_rle_scale_col`,
and :func:`_rle_join_cols`.
The nearest-neighbour mapping ``src = floor(dst * src_size / dst_size)``
is bit-exact with ``cv2.INTER_NEAREST``.View on GitHub (pinned to 7f254d9784)
Solutions
- Regenerate the RLE from a trusted source: build the boolean mask and use pycocotools.mask.encode to get valid counts.
- If decoding compressed counts yourself, verify the decoder (delta/Base48 paths) against pycocotools output before feeding from_coco_rle.
- Sanity-check counts with (np.asarray(counts) >= 0).all() before the call.
Example fix
# before counts = [0, -2, 6, 8] # negative run # after — regenerate from a mask from pycocotools import mask as mask_utils rle = mask_utils.encode(np.asfortranarray(mask.astype(np.uint8))) counts = list(rle["counts"]) if isinstance(rle["counts"], list) else rle # use encoded payload
Defensive patterns
Strategy: validation
Validate before calling
import numpy as np assert (np.asarray(rle["counts"], dtype=np.int64) >= 0).all(), "negative RLE count"
Try / catch
try:
cm = sv.CompactMask.from_coco_rle(rles, xyxy, image_shape=shape)
except ValueError as e:
if "non-negative" in str(e):
raise ValueError(f"corrupt RLE for mask, counts={rle['counts']}") from e
raise Prevention
- Only generate counts with a proven encoder (pycocotools.mask.encode); never hand-edit runs.
- Fuzz-test custom decoders against pycocotools round-trips.
- Checksum/validate annotation files downloaded from external sources before processing.
When it happens
Trigger: Passing counts like [0, -2, 6, 8] to CompactMask.from_coco_rle; delta-decoding logic upstream that produced negatives; hand-edited or corrupted annotation JSON.
Common situations: Custom RLE encoders with off-by-one bugs producing -1 runs; JSON corruption; incorrectly ported compressed-RLE decoders; LLM/script-generated annotation data.
Related errors
- The sum of COCO RLE counts must match the image area.
- COCO RLE counts must be one-dimensional.
- COCO RLE counts cannot be empty.
- Invalid COCO RLE counts.
- image_shape must contain positive height and width.
AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15).
Data as JSON: /api/errors/2fcbc401aba5138f.
Report an issue: GitHub.