{"record":{"id":"41c23f0cfca13152","repo":"roboflow/supervision","slug":"invalid-rectangle-dimensions","errorCode":null,"errorMessage":"Invalid rectangle dimensions.","messagePattern":"Invalid rectangle dimensions\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/supervision/draw/utils.py","lineNumber":465,"sourceCode":"    if image_np.ndim != 3 or image_np.shape[2] not in (3, 4):\n        raise ValueError(\"Image must have 3 or 4 channels.\")\n\n    # Validate opacity\n    if not 0.0 <= opacity <= 1.0:\n        raise ValueError(\"Opacity must be between 0.0 and 1.0.\")\n\n    rect_x = int(rect.x)\n    rect_y = int(rect.y)\n    rect_width = int(rect.width)\n    rect_height = int(rect.height)\n    # Validate rectangle dimensions\n    if (\n        rect_x < 0\n        or rect_y < 0\n        or rect_x + rect_width > scene.shape[1]\n        or rect_y + rect_height > scene.shape[0]\n    ):\n        raise ValueError(\"Invalid rectangle dimensions.\")\n\n    # Resize and isolate alpha channel\n    image_np = cast(\n        npt.NDArray[np.uint8], cv2.resize(image_np, (rect_width, rect_height))\n    )\n    alpha_channel = (\n        image_np[:, :, 3]\n        if image_np.shape[2] == 4\n        else np.ones((rect_height, rect_width), dtype=image_np.dtype) * 255\n    )\n    alpha_scaled = cv2.convertScaleAbs(alpha_channel * opacity)\n\n    # Perform blending\n    scene_roi = scene[rect_y : rect_y + rect_height, rect_x : rect_x + rect_width]\n    alpha_float = alpha_scaled.astype(np.float32) / 255.0\n    blended_roi = cv2.convertScaleAbs(\n        (1 - alpha_float[..., np.newaxis]) * scene_roi\n        + alpha_float[..., np.newaxis] * image_np[:, :, :3]","sourceCodeStart":447,"sourceCodeEnd":483,"githubUrl":"https://github.com/roboflow/supervision/blob/7f254d9784d4c37e0f03cd89ddee164c8db099c0/src/supervision/draw/utils.py#L447-L483","documentation":"Raised by draw_image when the target rectangle does not fit inside the scene: negative x/y, or width/height extending past the scene's right/bottom edges (checked against scene.shape[1] and scene.shape[0]). The function blends pixels within the rect, so out-of-bounds placement would index outside the frame. Coordinates are truncated to int before the check.","triggerScenarios":"Calling draw_image with Rect(x=-5, ...), or Rect(x=scene_width - 10, width=40) that overflows the right edge; also height/width large enough that x+width > scene.shape[1].","commonSituations":"Placing logos/badges at computed positions (e.g. top-right corner: x = W - logo_w with an off-by-one or already-scaled logo size); scenes resized after the rect was computed; scaled coordinates from a different resolution.","solutions":["Clamp the rect to the scene: rect.width = min(rect.width, scene.shape[1] - rect.x); rect.height = min(rect.height, scene.shape[0] - rect.y) with x,y clamped to >= 0","Recompute rect from current scene dimensions each frame instead of caching","For corner placement use explicit anchors: Rect(x=W - w - margin, y=margin, width=w, height=h)"],"exampleFix":"# before\nrect = Rect(x=scene.shape[1] - 50, y=10, width=60, height=60)  # overflows by 10\nscene = draw_image(scene, logo, opacity=0.8, rect=rect)\n\n# after\nrect = Rect(x=scene.shape[1] - 60, y=10, width=60, height=60)  # fits\nscene = draw_image(scene, logo, opacity=0.8, rect=rect)","handlingStrategy":"validation","validationCode":"def clamp_rect(rect, scene):\n    h, w = scene.shape[:2]\n    x = max(0, min(int(rect.x), w - 1))\n    y = max(0, min(int(rect.y), h - 1))\n    return Rect(\n        x=x,\n        y=y,\n        width=min(int(rect.width), w - x),\n        height=min(int(rect.height), h - y),\n    )\n\nscene = draw_image(scene, image, opacity=0.8, rect=clamp_rect(rect, scene))","typeGuard":"def rect_fits(rect: Rect, scene) -> bool:\n    \"\"\"True when rect lies fully inside the scene with positive size.\"\"\"\n    h, w = scene.shape[:2]\n    return (\n        rect.x >= 0 and rect.y >= 0 and rect.width > 0 and rect.height > 0\n        and rect.x + rect.width <= w and rect.y + rect.height <= h\n    )","tryCatchPattern":"try:\n    scene = draw_image(scene, image, opacity=0.8, rect=rect)\nexcept ValueError as e:\n    if 'rectangle dimensions' in str(e):\n        scene = draw_image(scene, image, opacity=0.8, rect=clamp_rect(rect, scene))\n    else:\n        raise","preventionTips":["Derive corner-anchored rects from the current frame size each draw call","After resizing scenes, recompute stored rect coordinates instead of reusing them"],"tags":["drawing","geometry","bounds-check","validation"],"backgroundTag":null,"analyzedSha":"7f254d9784d4c37e0f03cd89ddee164c8db099c0","analyzedAt":"2026-08-15T05:13:01.950Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}