Comfy-Org/ComfyUI · error · ValueError

Aspect ratios must be close: ar1/ar2={ar1/ar2:.2g}, allowed

Error message

Aspect ratios must be close: ar1/ar2={ar1/ar2:.2g}, allowed range {min_rel}–{max_rel} (limit {limit:.2g}).

What it means

ValueError from validate_images_aspect_ratio_closeness when the two images' aspect ratios differ too much: closeness C = max(ar1,ar2)/min(ar1,ar2) must stay under limit = max(max_rel, 1/min_rel). With strict=True the comparison is >= (limit itself fails); with strict=False only values strictly above limit fail. Used by nodes that need paired images (e.g., image+mask or first/last frame) to match proportions.

Source

Thrown at comfy_api_nodes/util/validation_utils.py:76

    strict: bool = False,  # True -> (min, max); False -> [min, max]
) -> float:
    """
    Validates that the two images' aspect ratios are 'close'.
    The closeness factor is C = max(ar1, ar2) / min(ar1, ar2)  (C >= 1).
    We require C <= limit, where limit = max(max_rel, 1.0 / min_rel).

    Returns the computed closeness factor C.
    """
    w1, h1 = get_image_dimensions(first_image)
    w2, h2 = get_image_dimensions(second_image)
    if min(w1, h1, w2, h2) <= 0:
        raise ValueError("Invalid image dimensions")
    ar1 = w1 / h1
    ar2 = w2 / h2
    closeness = max(ar1, ar2) / min(ar1, ar2)
    limit = max(max_rel, 1.0 / min_rel)
    if (closeness >= limit) if strict else (closeness > limit):
        raise ValueError(
            f"Aspect ratios must be close: ar1/ar2={ar1/ar2:.2g}, "
            f"allowed range {min_rel}–{max_rel} (limit {limit:.2g})."
        )
    return closeness


def validate_aspect_ratio_string(
    aspect_ratio: str,
    min_ratio: tuple[float, float] | None = None,  # e.g. (1, 4)
    max_ratio: tuple[float, float] | None = None,  # e.g. (4, 1)
    *,
    strict: bool = False,  # True -> (min, max); False -> [min, max]
) -> float:
    """Parses 'X:Y' and validates it against optional bounds. Returns the numeric ratio."""
    ar = _parse_aspect_ratio_string(aspect_ratio)
    _assert_ratio_bounds(ar, min_ratio=min_ratio, max_ratio=max_ratio, strict=strict)
    return ar

View on GitHub (pinned to 1c6d8d45b3)

Solutions

  1. Crop (not stretch) one image to the other's aspect ratio before pairing.
  2. Generate the reference/mask at the same resolution and aspect as the main image.
  3. If slight mismatch is acceptable, widen min_rel/max_rel only if the target API tolerates it — the limit exists because providers distort or reject mismatched pairs.

Example fix

# before
validate_images_aspect_ratio_closeness(img_16x9, img_1x1, min_rel=0.8, max_rel=1.25)
# after
# center-crop the 16:9 image to 1:1 first
crop = min(h, w)
img_sq = img_16x9[:, :crop, (w - crop) // 2:(w + crop) // 2, :]
validate_images_aspect_ratio_closeness(img_sq, img_1x1, min_rel=0.8, max_rel=1.25)
Defensive patterns

Strategy: validation

Validate before calling

def aspect_ratio(image: torch.Tensor) -> float:
    h = image.shape[1] if image.dim() == 4 else image.shape[0]
    w = image.shape[2] if image.dim() == 4 else image.shape[1]
    return w / h

def ratios_close(a: torch.Tensor, b: torch.Tensor, limit: float = 1.25) -> bool:
    ar1, ar2 = aspect_ratio(a), aspect_ratio(b)
    return max(ar1, ar2) / min(ar1, ar2) < limit

Prevention

When it happens

Trigger: Passing e.g. a 16:9 image and a 1:1 image with limit ~1.25: C = 1.78 > 1.25, so the ValueError with ar1/ar2 and the allowed range is raised at validation_utils.py:76.

Common situations: Mixing portrait and landscape sources; a mask or reference frame generated at a different resolution than the main image; resizing one input but not the other in the workflow.

Related errors


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