facebookresearch/detectron2 · error · ValueError
Cannot create polygons: Expect a list of polygons per instan
Error message
Cannot create polygons: Expect a list of polygons per instance. Got '{}' instead. What it means
Inside PolygonMasks construction, each entry must itself be a list of polygons for one instance. Passing e.g. a numpy array of shape (N, 2) or a flat coordinate array for one instance fails the list check in process_polygons.
Source
Thrown at detectron2/structures/masks.py:300
raise ValueError(
"Cannot create PolygonMasks: Expect a list of list of polygons per image. "
"Got '{}' instead.".format(type(polygons))
)
def _make_array(t: Union[torch.Tensor, np.ndarray]) -> np.ndarray:
# Use float64 for higher precision, because why not?
# Always put polygons on CPU (self.to is a no-op) since they
# are supposed to be small tensors.
# May need to change this assumption if GPU placement becomes useful
if isinstance(t, torch.Tensor):
t = t.cpu().numpy()
return np.asarray(t).astype("float64")
def process_polygons(
polygons_per_instance: List[Union[torch.Tensor, np.ndarray]],
) -> List[np.ndarray]:
if not isinstance(polygons_per_instance, list):
raise ValueError(
"Cannot create polygons: Expect a list of polygons per instance. "
"Got '{}' instead.".format(type(polygons_per_instance))
)
# transform each polygon to a numpy array
polygons_per_instance = [_make_array(p) for p in polygons_per_instance]
for polygon in polygons_per_instance:
if len(polygon) % 2 != 0 or len(polygon) < 6:
raise ValueError(f"Cannot create a polygon from {len(polygon)} coordinates.")
return polygons_per_instance
self.polygons: List[List[np.ndarray]] = [
process_polygons(polygons_per_instance) for polygons_per_instance in polygons
]
def to(self, *args: Any, **kwargs: Any) -> "PolygonMasks":
return self
@propertyView on GitHub (pinned to a2f4a8771a)
Solutions
- Wrap each instance's polygons in a list: [np.array([x0,y0,x1,y1,...])]
- Convert contour output: [contour.flatten() for contour in contours]
- Validate nesting depth (3 levels) before constructing PolygonMasks
Example fix
# before masks = PolygonMasks([[contour_array]]) # contour_array shape (N,2) # after masks = PolygonMasks([[[pt[0], pt[1]] for pt in contour_array]])
Defensive patterns
Strategy: validation
Validate before calling
assert all(isinstance(inst, list) for inst in polygons), 'each instance must be a list of polygon arrays'
Type guard
def is_valid_per_instance(p) -> bool:
return isinstance(p, list) and all(hasattr(poly, '__len__') for poly in p) Prevention
- Wrap per-instance polygon arrays in lists
- Flatten cv2 contours to [x0,y0,x1,y1,...] arrays before packing
When it happens
Trigger: PolygonMasks([[np.array([x0,y0,...])]]) is fine, but PolygonMasks([[np.array((N,2))]]) or an array-of-arrays per instance triggers it: any non-list per-instance value raises.
Common situations: Annotating with a single numpy array of polygon vertices per instance (common with cv2.findContours output) instead of a list of coordinate arrays.
Related errors
- Cannot create PolygonMasks: Expect a list of list of polygon
- Cannot match one checkpoint key to multiple keys in the mode
- Class with @configurable must have a 'from_config' classmeth
- {name} must take 'cfg' as the first argument!
- target of LazyCall must be a callable or defines a callable!
AI-assisted analysis of facebookresearch/detectron2@a2f4a8771a (2026-08-27).
Data as JSON: /api/errors/4a3e46413a399e3c.
Report an issue: GitHub.