roboflow/supervision · error · ValueError

Unsupported position: {position}

Error message

Unsupported position: {position}

What it means

Raised by resolve_text_background_xyxy() in supervision.annotators.utils when the `position` argument does not match any known Position enum branch (CENTER, CENTER_LEFT, CENTER_RIGHT, TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT, etc.). It is the terminal raise of the if/elif chain, so any unrecognized position value — usually a raw string or a custom enum — triggers it.

Source

Thrown at src/supervision/annotators/utils.py:130

            center_y,
            center_x + text_w // 2,
            center_y + text_h,
        )
    elif position == Position.CENTER_LEFT:
        return (
            center_x - text_w,
            center_y - text_h // 2,
            center_x,
            center_y + text_h // 2,
        )
    elif position == Position.CENTER_RIGHT:
        return (
            center_x,
            center_y - text_h // 2,
            center_x + text_w,
            center_y + text_h // 2,
        )
    raise ValueError(f"Unsupported position: {position}")


def get_color_by_index(color: Color | ColorPalette, idx: int) -> Color:
    """Resolve a color-like object to a concrete `Color` for an index."""
    color_like = cast(Any, color)
    # Accept ColorPalette-like objects without depending on their exact concrete class.
    if callable(getattr(color_like, "by_idx", None)):
        color_like = color_like.by_idx(idx)
    if isinstance(color_like, Color):
        return color_like
    return Color(
        r=int(color_like.r),
        g=int(color_like.g),
        b=int(color_like.b),
        a=int(getattr(color_like, "a", 255)),
    )

View on GitHub (pinned to 7f254d9784)

Solutions

  1. Pass the enum: position=sv.Position.TOP_LEFT (import from supervision).
  2. Check sv.Position.list() for the exact supported members in your installed version.
  3. Map config strings to enums explicitly rather than passing them raw.
  4. Upgrade/downgrade to the version whose Position members your code expects.

Example fix

// before
label_annotator = sv.LabelAnnotator(text_position='top_left')

// after
label_annotator = sv.LabelAnnotator(text_position=sv.Position.TOP_LEFT)
Defensive patterns

Strategy: validation

Validate before calling

supported = set(sv.Position.list())
if isinstance(position, str) and position.upper() in {p.upper() for p in supported}:
    position = sv.Position(position.upper())
assert getattr(position, 'value', position) in supported, position

Type guard

def is_supported_position(pos: object) -> bool:
    return isinstance(pos, sv.Position)

Prevention

When it happens

Trigger: Passing position='top_left' or Position.TOP_CENTER (unsupported member) to LabelAnnotator or any text-drawing helper; passing a coordinate tuple where the enum is expected.

Common situations: Config-driven annotator construction with unparsed strings; newer Position members used against older supervision; corner-position assumptions that are not implemented (e.g. CENTER_BOTTOM naming differences).

Related errors


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