keras-team/keras · error · ValueError

If `bounding_boxes['boxes']` is a list, then `bounding_boxes

Error message

If `bounding_boxes['boxes']` is a list, then `bounding_boxes['labels']` must also be a list.Received: bounding_boxes['labels']={labels}

What it means

validate_bounding_boxes enforces structural consistency between the 'boxes' and 'labels' entries of the bounding_boxes dict. When boxes is a Python list (typically a list of per-image arrays), labels must also be a Python list; passing a numpy array or tensor for labels while boxes is a list raises this ValueError immediately.

Source

Thrown at keras/src/layers/preprocessing/image_preprocessing/bounding_boxes/validation.py:133

    return bounding_boxes


def validate_bounding_boxes(bounding_boxes):
    if (
        not isinstance(bounding_boxes, dict)
        or "labels" not in bounding_boxes
        or "boxes" not in bounding_boxes
    ):
        raise ValueError(
            "Expected `bounding_boxes` agurment to be a "
            "dict with keys 'boxes' and 'labels'. Received: "
            f"bounding_boxes={bounding_boxes}"
        )
    boxes = bounding_boxes["boxes"]
    labels = bounding_boxes["labels"]
    if isinstance(boxes, list):
        if not isinstance(labels, list):
            raise ValueError(
                "If `bounding_boxes['boxes']` is a list, then "
                "`bounding_boxes['labels']` must also be a list."
                f"Received: bounding_boxes['labels']={labels}"
            )
        if len(boxes) != len(labels):
            raise ValueError(
                "If `bounding_boxes['boxes']` and "
                "`bounding_boxes['labels']` are both lists, "
                "they must have the same length. Received: "
                f"len(bounding_boxes['boxes'])={len(boxes)} and "
                f"len(bounding_boxes['labels'])={len(labels)} and "
            )
    elif tf_utils.is_ragged_tensor(boxes):
        if not tf_utils.is_ragged_tensor(labels):
            raise ValueError(
                "If `bounding_boxes['boxes']` is a Ragged tensor, "
                " `bounding_boxes['labels']` must also be a "
                "Ragged tensor. "

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Make labels a list: {'boxes': [b1, b2], 'labels': [l1, l2]} where each li has the matching box count
  2. Or convert both sides to tensors: boxes -> tensor of shape (batch, num_boxes, 4), labels -> tensor (batch, num_boxes)
  3. If image box counts differ, pad boxes to a common num_boxes before stacking

Example fix

# before
bbs = {'boxes': [boxes_img0, boxes_img1], 'labels': np.array([labels_img0, labels_img1])}
dense = densify_bounding_boxes(bbs)
# after
bbs = {'boxes': [boxes_img0, boxes_img1], 'labels': [labels_img0, labels_img1]}
dense = densify_bounding_boxes(bbs)
Defensive patterns

Strategy: validation

Validate before calling

boxes, labels = bbs['boxes'], bbs['labels']
if isinstance(boxes, list) and not isinstance(labels, list):
    bbs['labels'] = list(labels)
if isinstance(boxes, list):
    assert len(boxes) == len(labels), 'boxes/labels length mismatch'

Type guard

def is_valid_bounding_boxes(bbs: dict) -> bool:
    boxes, labels = bbs.get('boxes'), bbs.get('labels')
    if isinstance(boxes, list):
        return isinstance(labels, list) and len(boxes) == len(labels)
    if hasattr(boxes, 'values'):  # RaggedTensor
        return hasattr(labels, 'values')
    if hasattr(boxes, 'shape'):
        r, lr = len(boxes.shape), len(getattr(labels, 'shape', ()))
        return (r == 2 and lr in (1, 2)) or (r == 3 and lr in (2, 3))
    return False

Try / catch

try:
    out = densify_bounding_boxes(bbs)
except ValueError as e:
    raise ValueError(f'Invalid bounding_boxes structure: {e}') from e

Prevention

When it happens

Trigger: Calling densify_bounding_boxes (or a preprocessing layer that calls it) with {'boxes': [arr1, arr2], 'labels': np.array([...])} — i.e. boxes as a per-image list but labels as a single array/tensor.

Common situations: Building detection batches manually where images have different box counts; converting labels to a tensor during preprocessing while leaving boxes as lists; mixing keras.ops/tf tensors with raw Python structures.

Related errors


AI-assisted analysis of keras-team/keras@7a34a03db6 (2026-08-25). Data as JSON: /api/errors/74810f70a80bb285. Report an issue: GitHub.