facebookresearch/detectron2 · error · ValueError

bbox has to be 1-dimensional. Got shape={bbox.shape}.

Error message

bbox has to be 1-dimensional. Got shape={bbox.shape}.

What it means

convert_to_coco_dict requires each annotation['bbox'] to be a 1-D array. If bbox is an np.ndarray with ndim != 1 (e.g. shape (1,4) or (N,4)), it cannot be interpreted as a single box and a ValueError is raised.

Source

Thrown at detectron2/data/datasets/coco.py:368

    for image_id, image_dict in enumerate(dataset_dicts):
        coco_image = {
            "id": image_dict.get("image_id", image_id),
            "width": int(image_dict["width"]),
            "height": int(image_dict["height"]),
            "file_name": str(image_dict["file_name"]),
        }
        coco_images.append(coco_image)

        anns_per_image = image_dict.get("annotations", [])
        for annotation in anns_per_image:
            # create a new dict with only COCO fields
            coco_annotation = {}

            # COCO requirement: XYWH box format for axis-align and XYWHA for rotated
            bbox = annotation["bbox"]
            if isinstance(bbox, np.ndarray):
                if bbox.ndim != 1:
                    raise ValueError(f"bbox has to be 1-dimensional. Got shape={bbox.shape}.")
                bbox = bbox.tolist()
            if len(bbox) not in [4, 5]:
                raise ValueError(f"bbox has to has length 4 or 5. Got {bbox}.")
            from_bbox_mode = annotation["bbox_mode"]
            to_bbox_mode = BoxMode.XYWH_ABS if len(bbox) == 4 else BoxMode.XYWHA_ABS
            bbox = BoxMode.convert(bbox, from_bbox_mode, to_bbox_mode)

            # COCO requirement: instance area
            if "segmentation" in annotation:
                # Computing areas for instances by counting the pixels
                segmentation = annotation["segmentation"]
                # TODO: check segmentation type: RLE, BinaryMask or Polygon
                if isinstance(segmentation, list):
                    polygons = PolygonMasks([segmentation])
                    area = polygons.area()[0].item()
                elif isinstance(segmentation, dict):  # RLE
                    area = mask_util.area(segmentation).item()
                else:

View on GitHub (pinned to a2f4a8771a)

Solutions

  1. Squeeze/flatten the box before assignment: bbox = np.asarray(box).reshape(-1) or box.squeeze(0)
  2. Emit one annotation dict per box row when iterating a (N,4) tensor
  3. Ensure lists are passed instead of nested arrays

Example fix

# before
ann['bbox'] = boxes.tensor.numpy()[:1]  # shape (1,4)
# after
ann['bbox'] = boxes.tensor.numpy()[0]  # shape (4,)
Defensive patterns

Strategy: type-guard

Validate before calling

import numpy as np
bbox = np.asarray(annotation['bbox'])
assert bbox.ndim == 1, f'bbox must be 1-D, got {bbox.shape}'

Type guard

def is_flat_bbox(b) -> bool:
    import numpy as np
    return not isinstance(b, np.ndarray) or b.ndim == 1

Prevention

When it happens

Trigger: Exporting predictions via convert_to_coco_json when Instances.pred_boxes.tensor rows (or user-built annotation dicts) are stored with an extra leading dimension, e.g. bbox = np.array([[x,y,w,h]]) instead of [x,y,w,h].

Common situations: Looping over batches/Instances without squeezing; stacking boxes into 2-D arrays and assigning them as single annotation bboxes; custom evaluators constructing annotation dicts from numpy arrays.

Related errors


AI-assisted analysis of facebookresearch/detectron2@a2f4a8771a (2026-08-27). Data as JSON: /api/errors/93e8fdc2a7c41413. Report an issue: GitHub.