roboflow/supervision · error · ValueError

Invalid table position. Supported values are: TOP_LEFT, TOP_

Error message

Invalid table position. Supported values are: TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT.

What it means

LineZoneAnnotator's constructor accepts table_position only from the four corner Position members (TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT); center positions like CENTER or CENTER_LEFT have no table layout, so anything outside the set is rejected at init.

Source

Thrown at src/supervision/detection/line_zone.py:794

            table_position: The position of the table.
            table_color: The color of the table.
            table_margin: The margin of the table from the image border.
            table_padding: The padding of the table.
            table_max_width: The maximum width of the table.
            text_color: The color of the text.
            text_scale: The scale of the text.
            text_thickness: The thickness of the text.
            force_draw_class_ids: Instead of writing the class names,
                on the table, write the class IDs. E.g. instead of `person: 6`,
                write `0: 6`.
        """
        if table_position not in {
            Position.TOP_LEFT,
            Position.TOP_RIGHT,
            Position.BOTTOM_LEFT,
            Position.BOTTOM_RIGHT,
        }:
            raise ValueError(
                "Invalid table position. Supported values are:"
                " TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT."
            )

        self.table_position = table_position
        self.table_color = table_color
        self.table_margin = table_margin
        self.table_padding = table_padding
        self.table_max_width = table_max_width
        self.text_color = text_color
        self.text_scale = text_scale
        self.text_thickness = text_thickness
        self.force_draw_class_ids = force_draw_class_ids

    def annotate(
        self,
        frame: npt.NDArray[np.uint8],
        line_zones: list[LineZone],

View on GitHub (pinned to 7f254d9784)

Solutions

  1. Use one of the four corners, e.g. sv.Position.BOTTOM_RIGHT (the common default for crossing tables).
  2. If you want the table elsewhere, draw it manually with cv2.putText at your coordinates instead of the annotator.
  3. Do not pass strings; pass sv.Position members.

Example fix

# before
 annotator = sv.LineZoneAnnotator(table_position="top_left")

# after
 annotator = sv.LineZoneAnnotator(table_position=sv.Position.TOP_LEFT)
Defensive patterns

Strategy: validation

Validate before calling

VALID_POSITIONS = {
    sv.Position.TOP_LEFT, sv.Position.TOP_RIGHT,
    sv.Position.BOTTOM_LEFT, sv.Position.BOTTOM_RIGHT,
}
if table_position not in VALID_POSITIONS:
    raise ValueError("table_position must be a corner Position")

Prevention

When it happens

Trigger: sv.LineZoneAnnotator(table_position=sv.Position.CENTER) or a string 'top_left' (strings are not accepted at all), or Position.BOTTOM_RIGHT of an older/newer enum variant that does not compare equal.

Common situations: Assuming table_position takes a string like other annotator color args; using sv.Position.CENTER from muscle memory; wanting a centered table and picking the nearest-looking enum.

Related errors


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