{"record":{"id":"74810f70a80bb285","repo":"keras-team/keras","slug":"if-bounding-boxes-boxes-is-a-list-then-boun","errorCode":null,"errorMessage":"If `bounding_boxes['boxes']` is a list, then `bounding_boxes['labels']` must also be a list.Received: bounding_boxes['labels']={labels}","messagePattern":"If `bounding_boxes\\['boxes'\\]` is a list, then `bounding_boxes\\['labels'\\]` must also be a list\\.Received: bounding_boxes\\['labels'\\]=(.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"keras/src/layers/preprocessing/image_preprocessing/bounding_boxes/validation.py","lineNumber":133,"sourceCode":"    return bounding_boxes\n\n\ndef validate_bounding_boxes(bounding_boxes):\n    if (\n        not isinstance(bounding_boxes, dict)\n        or \"labels\" not in bounding_boxes\n        or \"boxes\" not in bounding_boxes\n    ):\n        raise ValueError(\n            \"Expected `bounding_boxes` agurment to be a \"\n            \"dict with keys 'boxes' and 'labels'. Received: \"\n            f\"bounding_boxes={bounding_boxes}\"\n        )\n    boxes = bounding_boxes[\"boxes\"]\n    labels = bounding_boxes[\"labels\"]\n    if isinstance(boxes, list):\n        if not isinstance(labels, list):\n            raise ValueError(\n                \"If `bounding_boxes['boxes']` is a list, then \"\n                \"`bounding_boxes['labels']` must also be a list.\"\n                f\"Received: bounding_boxes['labels']={labels}\"\n            )\n        if len(boxes) != len(labels):\n            raise ValueError(\n                \"If `bounding_boxes['boxes']` and \"\n                \"`bounding_boxes['labels']` are both lists, \"\n                \"they must have the same length. Received: \"\n                f\"len(bounding_boxes['boxes'])={len(boxes)} and \"\n                f\"len(bounding_boxes['labels'])={len(labels)} and \"\n            )\n    elif tf_utils.is_ragged_tensor(boxes):\n        if not tf_utils.is_ragged_tensor(labels):\n            raise ValueError(\n                \"If `bounding_boxes['boxes']` is a Ragged tensor, \"\n                \" `bounding_boxes['labels']` must also be a \"\n                \"Ragged tensor. \"","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/keras-team/keras/blob/7a34a03db60bf60042242d6a556fc3be119046a5/keras/src/layers/preprocessing/image_preprocessing/bounding_boxes/validation.py#L115-L151","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Make labels a list: {'boxes': [b1, b2], 'labels': [l1, l2]} where each li has the matching box count","Or convert both sides to tensors: boxes -> tensor of shape (batch, num_boxes, 4), labels -> tensor (batch, num_boxes)","If image box counts differ, pad boxes to a common num_boxes before stacking"],"exampleFix":"# before\nbbs = {'boxes': [boxes_img0, boxes_img1], 'labels': np.array([labels_img0, labels_img1])}\ndense = densify_bounding_boxes(bbs)\n# after\nbbs = {'boxes': [boxes_img0, boxes_img1], 'labels': [labels_img0, labels_img1]}\ndense = densify_bounding_boxes(bbs)","handlingStrategy":"validation","validationCode":"boxes, labels = bbs['boxes'], bbs['labels']\nif isinstance(boxes, list) and not isinstance(labels, list):\n    bbs['labels'] = list(labels)\nif isinstance(boxes, list):\n    assert len(boxes) == len(labels), 'boxes/labels length mismatch'","typeGuard":"def is_valid_bounding_boxes(bbs: dict) -> bool:\n    boxes, labels = bbs.get('boxes'), bbs.get('labels')\n    if isinstance(boxes, list):\n        return isinstance(labels, list) and len(boxes) == len(labels)\n    if hasattr(boxes, 'values'):  # RaggedTensor\n        return hasattr(labels, 'values')\n    if hasattr(boxes, 'shape'):\n        r, lr = len(boxes.shape), len(getattr(labels, 'shape', ()))\n        return (r == 2 and lr in (1, 2)) or (r == 3 and lr in (2, 3))\n    return False","tryCatchPattern":"try:\n    out = densify_bounding_boxes(bbs)\nexcept ValueError as e:\n    raise ValueError(f'Invalid bounding_boxes structure: {e}') from e","preventionTips":["Keep boxes and labels in the same structure type (both lists, both ragged, or both dense tensors)","Validate the dict once at data-loading time, not per batch"],"tags":["keras","bounding-boxes","input-validation","object-detection"],"backgroundTag":"input-shape-validation-failed","analyzedSha":"7a34a03db60bf60042242d6a556fc3be119046a5","analyzedAt":"2026-08-25T21:25:25.994Z","schemaVersion":2},"datasetVersion":"2026-08-26T02:17:13.382Z"}