Comfy-Org/ComfyUI · error · ValueError

Connect at least one keyframe image.

Error message

Connect at least one keyframe image.

What it means

Thrown by the FLUX.3 image-to-video node when the keyframes Autogrow input contains zero images. _flux3_collect_images walks the Autogrow entries and returns an empty list when nothing is connected, so the node refuses to build the request because an animation needs at least one keyframe.

Source

Thrown at comfy_api_nodes/nodes_bfl.py:1327

        )

    @classmethod
    async def execute(
        cls,
        prompt: str,
        keyframes: IO.Autogrow.Type,
        placement: dict,
        aspect_ratio: str,
        duration: str,
        resolution: str,
        generate_audio: bool,
        safety_tolerance: int,
        seed: int,
    ) -> IO.NodeOutput:
        fields = cls.common_fields(prompt, aspect_ratio, duration, resolution, generate_audio, safety_tolerance)
        images = _flux3_collect_images(keyframes, "keyframes")
        if not images:
            raise ValueError("Connect at least one keyframe image.")
        times = None
        if placement["placement"] == "at times":
            times = _flux3_parse_times(placement["times"], len(images), fields["duration"])
        elif len(images) >= 3 and fields["duration"] == "auto":
            # spread images land evenly between the first and last, which needs a known length
            raise ValueError(
                f"Spreading {len(images)} images across the clip needs an explicit duration: "
                "set duration, or place the images yourself with 'at times'."
            )
        urls = await upload_images_to_comfyapi(
            cls, images, max_images=_FLUX3_MAX_IMAGES, wait_label="Uploading keyframes"
        )
        request = Flux3ImageToVideoRequest(
            keyframes=list(zip(times, urls)) if times is not None else urls,
            **fields,
        )
        return await _flux3_execute(cls, request)

View on GitHub (pinned to 1c6d8d45b3)

Solutions

  1. Connect at least one LoadImage/Image output into the first keyframes Autogrow slot.
  2. If you want text-to-video with no keyframes, use the plain FLUX.3 text-to-video node instead.
  3. Verify the upstream image node actually emits a non-empty batch (check its output preview).
Defensive patterns

Strategy: validation

Validate before calling

keyframe_count = sum(1 for entry in keyframes if entry is not None)
if keyframe_count == 0:
    raise UserError('Connect at least one keyframe image before queueing.')

Type guard

def has_keyframes(keyframes) -> bool:
    return any(entry is not None and len(entry) > 0 for entry in keyframes)

Prevention

When it happens

Trigger: Executing Flux3Keyframe node with no IMAGE wires attached to any keyframes slot; or all keyframe Autogrow inputs left unconnected while expecting the node to fall back to text-to-video.

Common situations: User switches from the text-to-video FLUX.3 node to the keyframe node but forgets to wire images; UI saves a workflow with Autogrow slots the user thought were optional; batch upstream node produces an empty batch that gets filtered out before collection.

Related errors


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