roboflow/supervision · error · ValueError
Either absolute_distance or relative_distance must be set.
Error message
Either absolute_distance or relative_distance must be set.
What it means
The keep-nearby-mask-components style helper needs a distance threshold to decide which connected components are 'near' the main one; the threshold comes either from relative_distance (fraction of the mask diagonal) or absolute_distance (pixels). If both are None there is no way to compute a threshold, so a ValueError is raised.
Source
Thrown at src/supervision/detection/utils/masks.py:483
if num_labels <= 1:
return cast(npt.NDArray[np.bool_], mask.copy())
areas = stats[1:, cv2.CC_STAT_AREA]
max_area = int(areas.max())
candidates = 1 + np.flatnonzero(areas == max_area)
# Use coordinates for equal-area ties so native and fallback labels agree.
main_label = min(
(int(label) for label in candidates),
key=lambda label: (int(stats[label, 0]), int(stats[label, 1]), label),
)
if relative_distance is not None:
diagonal = float(np.hypot(height, width))
threshold = float(relative_distance) * diagonal
elif absolute_distance is not None:
threshold = float(absolute_distance)
else:
raise ValueError("Either absolute_distance or relative_distance must be set.")
keep_labels: npt.NDArray[np.bool_] = np.zeros(num_labels, dtype=bool)
keep_labels[main_label] = True
if mode == "centroid":
differences = centroids[1:] - centroids[main_label]
distances = np.sqrt(np.sum(differences**2, axis=1))
nearby = 1 + np.where(distances <= threshold)[0]
keep_labels[nearby] = True
elif mode == "edge":
main_mask = labels == main_label
if np.isnan(threshold) or threshold < 0:
nearby_main = np.zeros_like(main_mask)
elif np.isposinf(threshold):
nearby_main = np.ones_like(main_mask)
else:
fixed_distances = _chamfer_distances(main_mask)
distances = fixed_distances.astype(np.float32) / 65536View on GitHub (pinned to 7f254d9784)
Solutions
- Pass relative_distance (e.g. 0.2 = 20% of the diagonal) for resolution-independent behavior.
- Or pass absolute_distance in pixels when you know the expected component spacing.
- If wrapping the API, set your own default for one of the two parameters.
Example fix
# before
filtered = filter_non_zero_mask_areas(mask=mask) # no distance arg
# after
filtered = filter_non_zero_mask_areas(
mask=mask, relative_distance=0.2
) Defensive patterns
Strategy: validation
Validate before calling
if relative_distance is None and absolute_distance is None:
relative_distance = 0.2 # app default: 20% of mask diagonal
result = filter_non_zero_mask_areas(
mask=mask, relative_distance=relative_distance, absolute_distance=absolute_distance
) Prevention
- Always pass one of the two distance arguments.
- Prefer relative_distance for resolution-independent pipelines.
- Set an explicit default in your wrapper instead of relying on the library to have one.
When it happens
Trigger: Calling the function with neither keyword argument, or passing relative_distance=None explicitly intending a default; both branches are checked and the else clause fires.
Common situations: Copy-pasting a call and deleting the 'unused' distance argument; wrapping the function and forwarding **kwargs where the distance key was never set; assuming absolute_distance defaults to something sane.
Related errors
- Incorrect connectivity value. Possible connectivity values:
- mode must be 'edge' or 'centroid'
- coordinate_convention must be 'inclusive' or 'exclusive', go
- masks_true and masks_detection must be 3D (N, H, W); got ndi
- MeanAverageRecall with `MetricTarget.MASKS` requires detecti
AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15).
Data as JSON: /api/errors/83fdf132a2ff1509.
Report an issue: GitHub.