keras-team/keras · error · ValueError

If `bounding_boxes['boxes']` is a Ragged tensor, `bounding_

Error message

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

What it means

If 'boxes' is a RaggedTensor, validate_bounding_boxes requires 'labels' to be a RaggedTensor too, because raggedness encodes the per-image box counts and must match on both sides. A dense tensor or list for labels cannot be aligned with ragged boxes.

Source

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

    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. "
                f"Received: bounding_boxes['labels']={labels}"
            )
    else:
        boxes_shape = current_backend.shape(boxes)
        labels_shape = current_backend.shape(labels)
        if len(boxes_shape) == 2:  # (boxes, 4)
            if len(labels_shape) not in {1, 2}:
                raise ValueError(
                    "Found "
                    f"bounding_boxes['boxes'].shape={boxes_shape} "
                    "and expected bounding_boxes['labels'] to have "
                    "rank 1 or 2, but received: "
                    f"bounding_boxes['labels'].shape={labels_shape} "
                )
        elif len(boxes_shape) == 3:

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Convert labels to a RaggedTensor with the same row partition: tf.ragged.constant(list_of_label_arrays)
  2. Or use from_row_splits so labels share boxes.row_splits
  3. Or densify boxes first (pad to max box count), then use dense tensors for both

Example fix

# before
bbs = {'boxes': tf.ragged.constant(box_lists), 'labels': np.array(label_lists)}
# after
bbs = {'boxes': tf.ragged.constant(box_lists),
        'labels': tf.ragged.constant(label_lists)}
Defensive patterns

Strategy: validation

Validate before calling

if hasattr(bbs['boxes'], 'values') and not hasattr(bbs['labels'], 'values'):
    import tensorflow as tf
    bbs['labels'] = tf.ragged.stack(list(bbs['labels']))

Type guard

def boxes_labels_same_raggedness(bbs):
    b, l = bbs['boxes'], bbs['labels']
    return hasattr(b, 'values') == hasattr(l, 'values')

Prevention

When it happens

Trigger: densify_bounding_boxes with boxes as a tf.RaggedTensor (batch of varying box counts) but labels as a dense tensor or Python list.

Common situations: tf.data pipelines producing ragged boxes; converting only the boxes side to ragged to handle variable box counts while labels stay dense; TF2 detection data loaders.

Related errors


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