Comfy-Org/ComfyUI · error · ValueError

bboxes element 'bbox' must contain four numbers

Error message

bboxes element 'bbox' must contain four numbers

What it means

After confirming bbox is a 4-item sequence, elements_to_boxes converts each entry with float(v)/1000.0; if any entry is None, a non-numeric string, or a nested list, float() raises TypeError/ValueError which is caught and re-raised as this clearer message.

Source

Thrown at comfy_extras/nodes_bounding_boxes.py:217

    return isinstance(bbox, (list, tuple)) and len(bbox) == 4


def _looks_like_bbox(box: dict) -> bool:
    return all(key in box for key in ("x", "y", "width", "height"))


def elements_to_boxes(elements: list, width: int, height: int) -> list:
    boxes = []
    for element in elements:
        if not isinstance(element, dict):
            continue
        bbox = element.get("bbox")
        if not (isinstance(bbox, (list, tuple)) and len(bbox) == 4):
            raise ValueError("bboxes element is missing a valid 'bbox' [ymin, xmin, ymax, xmax]")
        try:
            ymin, xmin, ymax, xmax = (float(v) / 1000.0 for v in bbox)
        except (TypeError, ValueError):
            raise ValueError("bboxes element 'bbox' must contain four numbers")
        etype = "text" if element.get("type") == "text" else "obj"
        boxes.append({
            "x": round(min(xmin, xmax) * width),
            "y": round(min(ymin, ymax) * height),
            "width": round(abs(xmax - xmin) * width),
            "height": round(abs(ymax - ymin) * height),
            "metadata": {
                "type": etype,
                "text": element.get("text", "") if etype == "text" else "",
                "desc": element.get("desc", ""),
                "palette": element.get("color_palette", []) or [],
            },
        })
    return boxes


def boxes_from_input(data, width: int, height: int) -> list:
    if data is None:

View on GitHub (pinned to 1c6d8d45b3)

Solutions

  1. Sanitize bbox entries: replace None/invalid with 0 or drop the element before conversion
  2. Coerce strings to floats upstream ([float(v) if str else v]) or strip units
  3. Validate each element's bbox numerics before passing to elements_to_boxes

Example fix

// before
{"bbox": [0, 0, null, 500]}

// after
{"bbox": [0, 0, 0, 500]}
Defensive patterns

Strategy: validation

Validate before calling

def bbox_numbers_ok(el: dict) -> bool:
    b = el.get('bbox')
    if not (isinstance(b, (list, tuple)) and len(b) == 4):
        return False
    return all(isinstance(v, (int, float)) and not isinstance(v, bool) for v in b)

Type guard

def has_numeric_bbox(el: dict) -> bool:
    b = el.get('bbox', ())
    return len(b) == 4 and all(isinstance(v, (int, float)) for v in b)

Try / catch

try:
    boxes = elements_to_boxes(elements, w, h)
except ValueError as e:
    if 'must contain four numbers' in str(e):
        for el in elements:
            el['bbox'] = [float(v) if not isinstance(v, bool) else 0 for v in el.get('bbox', [0,0,0,0])]
        boxes = elements_to_boxes(elements, w, h)
    else:
        raise

Prevention

When it happens

Trigger: bbox = [0, 0, 'n/a', 500]; bbox containing None (common in JSON with missing optional fields); bbox = [[0],[0],[1],[1]] nested lists; strings with units like '50px'.

Common situations: Hand-written or LLM-generated bbox JSON with nulls for undetected coordinates; scraped data where coordinates are strings with whitespace/units.

Related errors


AI-assisted analysis of Comfy-Org/ComfyUI@1c6d8d45b3 (2026-08-14). Data as JSON: /api/errors/4810f802fed2136c. Report an issue: GitHub.