roboflow/supervision · error · ValueError

Overlap values must be greater than or equal to 0. Received:

Error message

Overlap values must be greater than or equal to 0. Received: {overlap_wh}

What it means

Raised by InferenceSlicer._validate_overlap when either component of overlap_wh is negative. Slice overlap is a pixel count shared between adjacent tiles and must be zero or positive; negative overlap would mean tiles skip pixels of the image. Note _normalize_overlap_wh already rejects negative ints and tuples, so reaching this check usually means the values were passed already-normalized or bypassed normalization.

Source

Thrown at src/supervision/detection/tools/inference_slicer.py:766

        y_max = np.clip(y_min + slice_height, 0, image_height)

        offsets: npt.NDArray[Any] = np.stack(
            [x_min, y_min, x_max, y_max],
            axis=-1,
        ).reshape(-1, 4)

        return offsets

    @staticmethod
    def _validate_overlap(
        slice_wh: tuple[int, int],
        overlap_wh: tuple[int, int],
    ) -> None:
        overlap_w, overlap_h = overlap_wh
        slice_w, slice_h = slice_wh

        if overlap_w < 0 or overlap_h < 0:
            raise ValueError(
                "Overlap values must be greater than or equal to 0. "
                f"Received: {overlap_wh}"
            )

        if overlap_w >= slice_w or overlap_h >= slice_h:
            raise ValueError(
                "`overlap_wh` must be smaller than `slice_wh` in both dimensions "
                f"to keep a positive stride. Received overlap_wh={overlap_wh}, "
                f"slice_wh={slice_wh}."
            )

View on GitHub (pinned to 7f254d9784)

Solutions

  1. Use overlap_wh >= 0 in both components; 0 means no overlap between tiles.
  2. Fix the conversion formula: overlap = max(0, slice_wh - stride).
  3. Pass overlap through the constructor (int or 2-tuple) so normalization handles validation.

Example fix

# before
overlap = stride - slice_wh  # negative when stride > slice_wh
slicer = sv.InferenceSlicer(callback=cb, slice_wh=slice_wh, overlap_wh=(overlap, overlap))

# after
overlap = max(0, slice_wh - stride)
slicer = sv.InferenceSlicer(callback=cb, slice_wh=slice_wh, overlap_wh=(overlap, overlap))
Defensive patterns

Strategy: validation

Validate before calling

overlap_w, overlap_h = (max(0, int(v)) for v in (overlap_w, overlap_h))
slicer = sv.InferenceSlicer(callback=cb, slice_wh=(slice_w, slice_h), overlap_wh=(overlap_w, overlap_h))

Type guard

def is_non_negative_overlap(overlap_wh) -> bool:
    return all(v >= 0 for v in overlap_wh)

Prevention

When it happens

Trigger: Computing overlap dynamically (e.g. overlap = slice_wh - stride) that goes negative when stride exceeds slice size; calling _validate_overlap directly with negative entries; a custom subclass skipping _normalize_overlap_wh.

Common situations: Stride-based config converted to overlap with wrong operand order (overlap = stride - slice_wh instead of slice_wh - stride); arithmetic on config values that underflows for small slices.

Related errors


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