roboflow/supervision · error · ValueError
LabelMe polygon shape (label={label}) has {len(points)} poin
Error message
LabelMe polygon shape (label={label}) has {len(points)} point(s); expected at least 3. What it means
Raised by the LabelMe dataset loader when a non-rectangle shape (polygon, linestrip-like types treated as polygons) contains fewer than 3 points. A polygon needs at least 3 vertices to enclose an area and be converted to a bounding box, so the loader refuses to convert it. The offending shape's label is included in the message to help locate it in the JSON annotation file.
Source
Thrown at src/supervision/dataset/formats/labelme.py:127
)
points = np.array(points_raw, dtype=np.float32)
if points.ndim != 2 or points.shape[1] != 2:
raise ValueError(
f"LabelMe shape of type {shape_type!r} (label={label!r}) has "
f"malformed points: expected an (N, 2) array, got shape "
f"{points.shape}."
)
if shape_type == "rectangle":
if len(points) < 2:
raise ValueError(
f"LabelMe rectangle shape (label={label!r}) has "
f"{len(points)} point(s); expected at least 2."
)
xyxy = _rectangle_to_xyxy(points)
polygon = _xyxy_to_polygon(xyxy)
else:
if len(points) < 3:
raise ValueError(
f"LabelMe polygon shape (label={label!r}) has "
f"{len(points)} point(s); expected at least 3."
)
xyxy = polygon_to_xyxy(polygon=points).astype(np.float32)
polygon = points
xyxy_list.append(xyxy)
class_ids.append(class_to_index[label])
if with_masks:
polygons.append(polygon)
if skipped_types:
warnings.warn(
f"Skipped unsupported LabelMe shape type(s) {sorted(skipped_types)}; "
f"only {list(SUPPORTED_SHAPE_TYPES)} are imported.",
UserWarning,
stacklevel=2,
)
View on GitHub (pinned to 7f254d9784)
Solutions
- Open the LabelMe JSON file named in the surrounding error context and find the shape with the reported label; add a third point or delete the shape.
- If the shape was meant to be a line, either convert it to shape_type 'rectangle' with 2 diagonal points or filter it out before loading.
- Write a small pre-processing pass over the dataset that drops or repairs shapes with len(points) < 3 before calling the loader.
- Regenerate the annotation from the source tool (e.g. re-draw in LabelMe) if the file is corrupted.
Example fix
// before (labelme JSON)
{"label": "door", "shape_type": "polygon", "points": [[10, 10], [40, 10]]}
// after
{"label": "door", "shape_type": "polygon", "points": [[10, 10], [40, 10], [40, 40]]} Defensive patterns
Strategy: validation
Validate before calling
import json
def valid_labelme_shapes(path):
with open(path) as f:
data = json.load(f)
for shape in data.get("shapes", []):
pts = shape.get("points", [])
if shape.get("shape_type") == "rectangle":
if len(pts) < 2:
return False
elif len(pts) < 3:
return False
return True Try / catch
try:
ds = sv.DetectionDataset.from_labelme(...)
except ValueError as e:
if "expected at least 3" in str(e):
log.warning("skipping malformed annotation: %s", e)
else:
raise Prevention
- Run a dataset lint pass that flags shapes with fewer points than their shape_type requires before loading.
- Prefer re-exporting from the LabelMe tool rather than hand-editing points arrays.
- In CI for annotation datasets, assert every shape has >= 3 points (>= 2 for rectangles).
When it happens
Trigger: Loading a LabelMe dataset (DetectionDataset.from_labelme or the labelme format module) where a shapes[] entry with shape_type other than 'rectangle' has a points array of length 0, 1, or 2. Happens with hand-drawn annotations, corrupted files, or exports from tools that emit degenerate polygons.
Common situations: Manually annotated datasets where a shape was started but not finished; third-party converters that emit empty points arrays; JSON edits that truncated points; linestrip shapes (2 points) being treated as polygons.
Related errors
- Detections must have class_id attribute.
- Detections class_id must be a subset of source_to_target_map
- Class {class_name} not found in target classes. source_class
- Cannot export dataset: image paths {first_path} and {image_p
- The keys of the images and annotations dictionaries must mat
AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15).
Data as JSON: /api/errors/13be58e12d78df03.
Report an issue: GitHub.