{"record":{"id":"2691faab5247101a","repo":"Comfy-Org/ComfyUI","slug":"aspect-ratio-ar-2g-must-be-op-hi-2g","errorCode":null,"errorMessage":"Aspect ratio `{ar:.2g}` must be {op} {hi:.2g}.","messagePattern":"Aspect ratio `(.+?)` must be (.+?) (.+?)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"comfy_api_nodes/util/validation_utils.py","lineNumber":230,"sourceCode":"    min_ratio: tuple[float, float] | None = None,\n    max_ratio: tuple[float, float] | None = None,\n    strict: bool = True,\n) -> None:\n    \"\"\"Validate a numeric aspect ratio against optional min/max ratio bounds.\"\"\"\n    lo = _ratio_from_tuple(min_ratio) if min_ratio is not None else None\n    hi = _ratio_from_tuple(max_ratio) if max_ratio is not None else None\n\n    if lo is not None and hi is not None and lo > hi:\n        lo, hi = hi, lo  # normalize order if caller swapped them\n\n    if lo is not None:\n        if (ar <= lo) if strict else (ar < lo):\n            op = \"<\" if strict else \"≤\"\n            raise ValueError(f\"Aspect ratio `{ar:.2g}` must be {op} {lo:.2g}.\")\n    if hi is not None:\n        if (ar >= hi) if strict else (ar > hi):\n            op = \"<\" if strict else \"≤\"\n            raise ValueError(f\"Aspect ratio `{ar:.2g}` must be {op} {hi:.2g}.\")\n\n\ndef _parse_aspect_ratio_string(ar_str: str) -> float:\n    \"\"\"Parse 'X:Y' with integer parts into a positive float ratio X/Y.\"\"\"\n    parts = ar_str.split(\":\")\n    if len(parts) != 2:\n        raise ValueError(f\"Aspect ratio must be 'X:Y' (e.g., 16:9), got '{ar_str}'.\")\n    try:\n        a = int(parts[0].strip())\n        b = int(parts[1].strip())\n    except ValueError as exc:\n        raise ValueError(f\"Aspect ratio must contain integers separated by ':', got '{ar_str}'.\") from exc\n    if a <= 0 or b <= 0:\n        raise ValueError(f\"Aspect ratio parts must be positive integers, got {a}:{b}.\")\n    return a / b\n","sourceCodeStart":212,"sourceCodeEnd":246,"githubUrl":"https://github.com/Comfy-Org/ComfyUI/blob/1c6d8d45b3693bfbb32385b410d813a7fd6be216/comfy_api_nodes/util/validation_utils.py#L212-L246","documentation":"Raised by _assert_ratio_bounds() in comfy_api_nodes/util/validation_utils.py when a numeric aspect ratio is at or above the provider's maximum ratio (strict mode rejects equality too; strict=False allows ar == hi). Mirrors the min-bound check; bounds given as tuples like (4, 1) meaning 4:1, with automatic order normalization if the caller swapped min/max.","triggerScenarios":"Calling a node wrapped with _assert_ratio_bounds(ar, max_ratio=(4,1)) with ar >= 4.0 — e.g. a 5:1 ultrawide banner request. Strict mode also rejects exactly 4.0; the message embeds '<' as the required relation.","commonSituations":"Ultrawide banner/cinematic requests beyond provider support; width/height swapped upstream inverting the ratio; custom-ratio widgets used with values outside the provider's supported list.","solutions":["Reduce the aspect ratio to below the provider maximum (commonly 4:1).","Verify width/height wiring — a swap turns 4:1 into 1:4 and trips the other bound.","Use a preset ratio from the node's dropdown known to be supported.","For genuinely extreme formats, generate at max ratio and crop/resize locally afterward."],"exampleFix":"# before\n_assert_ratio_bounds(5.0, max_ratio=(4, 1))  # ValueError: Aspect ratio `5` must be < 4.\n\n# after\n_assert_ratio_bounds(3.5, max_ratio=(4, 1))  # 7:2, inside bounds","handlingStrategy":"validation","validationCode":"MAX = 4/1\nif ar >= MAX:\n    ar = MAX - 1e-6  # or clamp / reject with a friendly message","typeGuard":null,"tryCatchPattern":"try: _assert_ratio_bounds(ar, max_ratio=(4,1)) except ValueError as e: raise UserVisibleError(str(e)) from e","preventionTips":["Keep ultrawide requests under the provider max (typically 4:1).","Verify dimension order — swaps invert the ratio.","Crop locally when you need more extreme formats than the API allows."],"tags":["api-nodes","validation","aspect-ratio"],"backgroundTag":null,"analyzedSha":"1c6d8d45b3693bfbb32385b410d813a7fd6be216","analyzedAt":"2026-08-14T19:37:18.893Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}