Comfy-Org/ComfyUI · error · ValueError
Ratios must be positive, got {a}:{b}.
Error message
Ratios must be positive, got {a}:{b}. What it means
Raised by the private helper _ratio_from_tuple() in comfy_api_nodes/util/validation_utils.py when a min_ratio/max_ratio bound tuple contains a zero or negative component. This is developer/config error, not user input error: the tuples are hardcoded by node authors to define provider aspect-ratio limits (e.g. (1, 4) meaning 1:4), and X:Y must have X,Y > 0.
Source
Thrown at comfy_api_nodes/util/validation_utils.py:205
f"Field '{field_name}' cannot be shorter than {min_length} characters; was {len(string)} characters long."
)
if max_length and len(string) > max_length:
raise Exception(
f" Field '{field_name} cannot be longer than {max_length} characters; was {len(string)} characters long."
)
def validate_container_format_is_mp4(video: Input.Video) -> None:
"""Validates video container format is MP4."""
container_format = video.get_container_format()
if container_format not in ["mp4", "mov,mp4,m4a,3gp,3g2,mj2"]:
raise ValueError(f"Only MP4 container format supported. Got: {container_format}")
def _ratio_from_tuple(r: tuple[float, float]) -> float:
a, b = r
if a <= 0 or b <= 0:
raise ValueError(f"Ratios must be positive, got {a}:{b}.")
return a / b
def _assert_ratio_bounds(
ar: float,
*,
min_ratio: tuple[float, float] | None = None,
max_ratio: tuple[float, float] | None = None,
strict: bool = True,
) -> None:
"""Validate a numeric aspect ratio against optional min/max ratio bounds."""
lo = _ratio_from_tuple(min_ratio) if min_ratio is not None else None
hi = _ratio_from_tuple(max_ratio) if max_ratio is not None else None
if lo is not None and hi is not None and lo > hi:
lo, hi = hi, lo # normalize order if caller swapped them
if lo is not None:View on GitHub (pinned to 1c6d8d45b3)
Solutions
- If you are the node author: fix the bound tuple to positive values; use None instead of 0 to mean 'no bound'.
- If unbounded is intended on one side, pass min_ratio=None / max_ratio=None rather than a degenerate tuple.
- If you are a user hitting this from a third-party node, update the node pack — it is a bug in the node, not your input; report it upstream with the traceback.
- Double-check ratio order conventions (w:h vs h:w) against the validator's callers before editing.
Example fix
# before _ratio_from_tuple((0, 1)) # ValueError: Ratios must be positive, got 0:1. # after bounds = None # no lower bound _ratio_from_tuple((1, 4)) # valid lower bound
Defensive patterns
Strategy: validation
Validate before calling
def valid_ratio_bound(t):
return t is None or (isinstance(t, tuple) and len(t) == 2 and all(x > 0 for x in t)) Prevention
- Node authors: pass None for unbounded sides instead of degenerate tuples.
- Unit-test bound tuples with positive components.
- Never translate '0:1' from provider docs literally into code.
When it happens
Trigger: A node implementation calls validate_aspect_ratio(..., min_ratio=(0, 1)) or max_ratio=(16, -9)) — a typo or a mistaken 'allow zero width' assumption. End users essentially cannot trigger it via widgets because bounds are baked into the node code.
Common situations: Custom-node authors copying provider docs that express limits as '0:1 to 1:0' (meaning fully unbounded) and passing them literally; refactor typos swapping a ratio for a dimension; or tests feeding synthetic bound tuples.
Related errors
- Aspect ratio `{ar:.2g}` must be {op} {lo:.2g}.
- Aspect ratio `{ar:.2g}` must be {op} {hi:.2g}.
- Aspect ratio must be 'X:Y' (e.g., 16:9), got '{ar_str}'.
- Aspect ratio must contain integers separated by ':', got '{a
- Aspect ratio parts must be positive integers, got {a}:{b}.
AI-assisted analysis of Comfy-Org/ComfyUI@1c6d8d45b3 (2026-08-14).
Data as JSON: /api/errors/47fe683f88dd62a5.
Report an issue: GitHub.