roboflow/supervision · error · ValueError

Edge indices must use the 1-based convention and be within t

Error message

Edge indices must use the 1-based convention and be within the available keypoint range [1, {vertex_count}], got {edge}.

What it means

Raised in Color.__post_init__ when a Color dataclass is constructed directly with any channel (r, g, b, or a) outside the 0-255 byte range. supervision validates eagerly at construction time because all downstream consumers (OpenCV drawing, image compositing) require byte-sized channel values. The message includes the offending (r, g, b, a) tuple so the out-of-range channel is immediately visible.

Source

Thrown at src/supervision/key_points/annotators.py:26

from supervision import _cv2 as cv2
from supervision.detection.utils.boxes import pad_boxes, spread_out_boxes
from supervision.draw.base import ImageType
from supervision.draw.color import Color
from supervision.draw.utils import draw_rounded_rectangle
from supervision.geometry.core import Rect
from supervision.key_points.core import KeyPoints
from supervision.key_points.skeletons import SKELETONS_BY_VERTEX_COUNT
from supervision.utils.conversion import ensure_cv2_image_for_class_method
from supervision.utils.logger import _get_logger

logger = _get_logger(__name__)


def _validate_edge_indices(edge: tuple[int, int], vertex_count: int) -> tuple[int, int]:
    """Validate 1-based skeleton edges and return zero-based vertex indexes."""
    vertex_a, vertex_b = edge
    if not (1 <= vertex_a <= vertex_count and 1 <= vertex_b <= vertex_count):
        raise ValueError(
            "Edge indices must use the 1-based convention and be within the "
            f"available keypoint range [1, {vertex_count}], got {edge}."
        )
    # Public skeleton definitions are 1-based; keypoint arrays are zero-based.
    return vertex_a - 1, vertex_b - 1


class BaseKeyPointAnnotator(ABC):
    @abstractmethod
    def annotate(self, scene: ImageType, key_points: KeyPoints) -> ImageType:
        pass


class VertexAnnotator(BaseKeyPointAnnotator):
    """
    A class that specializes in drawing skeleton vertices on images. It uses
    specified key points to determine the locations where the vertices should be
    drawn.

View on GitHub (pinned to 7f254d9784)

Solutions

  1. Clamp every channel to 0-255 before constructing, e.g. sv.Color(max(0, min(255, r)), ...).
  2. If your source values are 0-1 floats, convert with int(round(v * 255)) first.
  3. Prefer the classmethods from_rgb_tuple / from_bgr_tuple / from_rgba_tuple / from_bgra_tuple or from_hex, which validate per format and document expected ranges.
  4. Audit any code that adds/multiplies channel values (fade-in effects, mixing) and add a clamp helper at the boundary.

Example fix

# before
brightened = sv.Color(base.r + 60, base.g + 60, base.b + 60)  # may exceed 255

# after
clamp = lambda v: max(0, min(255, v))
brightened = sv.Color(clamp(base.r + 60), clamp(base.g + 60), clamp(base.b + 60))
Defensive patterns

Strategy: validation

Validate before calling

def clamp_channel(v: float) -> int:
    """Force any channel value into the 0-255 byte range Color requires."""
    return max(0, min(255, int(round(v))))

# before: sv.Color(r + 40, g + 40, b + 40)
# after:  sv.Color(clamp_channel(r + 40), clamp_channel(g + 40), clamp_channel(b + 40))

Type guard

def is_byte_color(r: float, g: float, b: float, a: float = 255) -> bool:
    """True if all channels are ints within 0-255, safe for sv.Color()."""
    return all(isinstance(v, int) and 0 <= v <= 255 for v in (r, g, b, a))

Prevention

When it happens

Trigger: Direct construction such as sv.Color(r=300, g=0, b=0), sv.Color(-1, 0, 0), or sv.Color(256, 256, 256, 300); arithmetic on colors without clamping, e.g. brightening via sv.Color(c.r + 50, c.g + 50, c.b + 50); passing floats or channel values from a library that uses 0-1 or 0-65535 ranges.

Common situations: Dynamic color math (tints, gradients, heatmaps) that overflows the byte range; migrating code from libraries with different color ranges (PIL RGB floats, CSS percentages, 16-bit image pipelines); reading channel values from external config or data files without bounds checking.

Related errors


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