Comfy-Org/ComfyUI · error · ValueError
Input video frame rate ({fps:.2f} fps) exceeds Aleph2's maxi
Error message
Input video frame rate ({fps:.2f} fps) exceeds Aleph2's maximum of 30 fps. What it means
Raised by the Runway Aleph2 video-to-video node when the input video's frame rate, read via video.get_frame_rate(), exceeds 30 fps (with a 0.01 tolerance). If the frame rate cannot be read the check is skipped, so it only fires when fps is determinable and above the limit. It fires before any upload happens.
Source
Thrown at comfy_api_nodes/nodes_runway.py:776
prompt: str,
video: Input.Video,
seed: int,
public_figure_threshold: str = "low",
keyframes: RunwayAleph2KeyframeChain | None = None,
prompt_images: RunwayAleph2PromptImageChain | None = None,
) -> IO.NodeOutput:
validate_string(prompt, min_length=1, max_length=1000)
validate_video_duration(
video,
min_duration=2.0,
max_duration=30.0,
)
try:
fps = float(video.get_frame_rate())
except Exception:
fps = None
if fps is not None and fps > 30.0 + 0.01:
raise ValueError(f"Input video frame rate ({fps:.2f} fps) exceeds Aleph2's maximum of 30 fps.")
if (keyframes and keyframes.items) and (prompt_images and prompt_images.items):
raise ValueError("Aleph2 accepts either keyframes or prompt images, not both.")
video_duration: float | None = None
try:
video_duration = video.get_duration()
except Exception:
video_duration = None
def _check_seconds(value: float, label: str) -> None:
if video_duration is not None and value > video_duration + 0.0001:
raise ValueError(f"{label} {value:.2f}s exceeds the input video duration ({video_duration:.2f}s).")
video_url = await upload_video_to_comfyapi(cls, video)
keyframe_models: list[RunwayAleph2KeyframeSeconds | RunwayAleph2KeyframeAt] = []
if keyframes is not None:View on GitHub (pinned to 1c6d8d45b3)
Solutions
- Re-encode or resample the video to 30 fps or lower before the node (e.g. ffmpeg -r 30)
- Use a video frame-rate conversion node upstream in the workflow
- If the source is genuinely high-fps, decimate frames rather than duplicating to keep duration correct
Example fix
# before
video_60fps = load_video("clip.mp4") # 60 fps
aleph2(prompt, video_60fps, ...)
# after
# shell: ffmpeg -i clip.mp4 -r 30 clip_30fps.mp4
video_30fps = load_video("clip_30fps.mp4")
aleph2(prompt, video_30fps, ...) Defensive patterns
Strategy: validation
Validate before calling
try:
fps = float(video.get_frame_rate())
except Exception:
fps = None
if fps is not None and fps > 30.01:
raise ValueError(f"Resample {fps:.2f} fps video to <=30 fps before Aleph2") Type guard
def is_aleph2_safe_fps(video) -> bool:
try:
return float(video.get_frame_rate()) <= 30.01
except Exception:
return True # check is skipped when fps is unreadable Try / catch
try:
await aleph2_execute(...)
except ValueError as e:
if "frame rate" in str(e):
video = reencode_at_30fps(video) # then retry
else:
raise Prevention
- Standardize inputs to 24/30 fps for Runway video nodes
- Check fps with ffprobe before wiring external footage
- Remember the check is skipped when fps is unreadable — do not rely on missing metadata
When it happens
Trigger: Passing a video with fps > 30.01 (e.g. 60 fps gameplay/screen capture, 50 fps PAL footage) to the Aleph2 node; video.get_frame_rate() must succeed for the check to run.
Common situations: Feeding 60fps phone footage or high-framerate screen recordings; mixing 60fps sources into a workflow built for cinematic 24/30fps material.
Related errors
- {label} {value:.2f}s exceeds the input video duration ({vide
- Asset video FPS must be in [24, 60], got {fps:.2f}.
- Aleph2 accepts either keyframes or prompt images, not both.
- Aleph2 supports at most 5 keyframes.
- Aleph2 supports at most 5 prompt images.
AI-assisted analysis of Comfy-Org/ComfyUI@1c6d8d45b3 (2026-08-14).
Data as JSON: /api/errors/f9b9ae9b02377ea1.
Report an issue: GitHub.