{"record":{"id":"8cd846c161e1c3b7","repo":"Comfy-Org/ComfyUI","slug":"normalized-element-boxes-need-canvas-width-and-can","errorCode":null,"errorMessage":"normalized element boxes need canvas_width and canvas_height to resolve to pixels","messagePattern":"normalized element boxes need canvas_width and canvas_height to resolve to pixels","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"comfy_extras/nodes_compositor.py","lineNumber":82,"sourceCode":"    if bboxes is None:\n        return []\n    if isinstance(bboxes, str):\n        text = bboxes.strip()\n        if not text:\n            return []\n        try:\n            bboxes = json.loads(text)\n        except (json.JSONDecodeError, ValueError) as exc:\n            raise ValueError(f\"bboxes string input is not valid JSON: {exc}\") from exc\n    probe = bboxes if isinstance(bboxes, list) else [bboxes]\n    if probe and isinstance(probe[0], list):\n        probe = probe[0]\n    has_elements = any(\n        isinstance(box, dict) and isinstance(box.get(\"bbox\"), (list, tuple))\n        for box in probe\n    )\n    if has_elements and (canvas_width <= 0 or canvas_height <= 0):\n        raise ValueError(\n            \"normalized element boxes need canvas_width and canvas_height to resolve to pixels\"\n        )\n    return boxes_from_input(bboxes, canvas_width, canvas_height)\n\n\ndef _item_mask_frame(mask, index: int) -> torch.Tensor | None:\n    if not isinstance(mask, torch.Tensor):\n        return None\n    if mask.shape[0] == 1:\n        return mask[:1]\n    if index < mask.shape[0]:\n        return mask[index : index + 1]\n    return None\n\n\ndef expand_item_frames(items: list[dict]) -> list[dict]:\n    frames = []\n    for item in items:","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/Comfy-Org/ComfyUI/blob/1c6d8d45b3693bfbb32385b410d813a7fd6be216/comfy_extras/nodes_compositor.py#L64-L100","documentation":"Element-style boxes (dicts with a normalized 'bbox' key) are stored in 0-1 normalized coordinates and must be multiplied by canvas_width/canvas_height to become pixels. If any element is detected in the input but either canvas dimension is <= 0 (unset, zero, or negative), resolution is impossible and the node raises this instead of producing boxes at nonsense coordinates.","triggerScenarios":"Passing element dicts like {\"bbox\": [0.1, 0.2, 0.5, 0.4]} to the compositor node while canvas_width and/or canvas_height are 0 or were left at defaults that resolve to 0. Raw pixel boxes (plain lists) do not trigger this — only elements do.","commonSituations":"Wiring layout-detection output (normalized element boxes) into a compositor whose canvas size comes from another optional input that is disconnected; workflows where the canvas is meant to be derived from the image but the sizing link was forgotten.","solutions":["Connect or set canvas_width and canvas_height to positive values matching the target composite (typically the base image's dimensions).","Convert normalized element boxes to pixel boxes upstream ([x*W, y*H, w*W, h*H]) if you cannot supply a canvas.","Verify the probe logic: the node detects elements by any dict having a 'bbox' list, so mixed inputs still require a canvas."],"exampleFix":"# before\nelements = [{\"bbox\": [0.1, 0.2, 0.5, 0.4]}]  # canvas_width=0\n# after\nelements = [{\"bbox\": [0.1, 0.2, 0.5, 0.4]}]  # canvas_width=1024, canvas_height=768","handlingStrategy":"validation","validationCode":"def has_elements(bboxes) -> bool:\n    probe = bboxes if isinstance(bboxes, list) else [bboxes]\n    if probe and isinstance(probe[0], list):\n        probe = probe[0]\n    return any(isinstance(b, dict) and isinstance(b.get(\"bbox\"), (list, tuple)) for b in probe)\n\ndef ensure_canvas(bboxes, w, h):\n    if has_elements(bboxes) and (w <= 0 or h <= 0):\n        raise ValueError(\"supply canvas dims for normalized boxes\")\n    return w, h","typeGuard":"def is_element_box(b) -> bool:\n    return isinstance(b, dict) and isinstance(b.get(\"bbox\"), (list, tuple))","tryCatchPattern":null,"preventionTips":["Always connect canvas_width/canvas_height when using element-style boxes.","Denormalize boxes to pixels upstream if canvas size is unknown at the node.","Remember: only pixel-list boxes work without a canvas."],"tags":["validation","bounding-boxes","normalized-coordinates","comfyui"],"backgroundTag":null,"analyzedSha":"1c6d8d45b3693bfbb32385b410d813a7fd6be216","analyzedAt":"2026-08-14T19:37:18.893Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}