Comfy-Org/ComfyUI · error · ValueError

Keyframe position {item.value:g}s is past the end of the {du

Error message

Keyframe position {item.value:g}s is past the end of the {duration} video; use 0-{duration_seconds:g}s (or switch the keyframe to fraction mode).

What it means

Raised by the Luma Ray 3.2 keyframe video node (comfy_api_nodes/nodes_luma.py:1249) when a keyframe in seconds-mode has a position beyond the video length (5.0s for '5s', 10.0s for '10s' at 24fps). The node rejects it before submission so the user can fix the position or switch the keyframe to fraction mode.

Source

Thrown at comfy_api_nodes/nodes_luma.py:1249

    ) -> IO.NodeOutput:
        validate_string(prompt, strip_whitespace=True, min_length=1, max_length=6000)
        items = keyframes.items if keyframes is not None else []
        if len(items) < 2:
            raise ValueError(
                "Connect at least 2 Luma Ray 3.2 Keyframe nodes "
                "(use Luma Ray 3.2 Image to Video for a single start/end frame)."
            )
        if len(items) > 64:
            raise ValueError(f"Ray 3.2 supports at most 64 keyframes; got {len(items)}.")
        maxframe = 120 if duration == "5s" else 240
        duration_seconds = maxframe / 24  # 5.0 or 10.0
        # Resolve each keyframe to an output-frame index, then order by position
        # (so the user can chain keyframes in any order — the position is what places them)
        placed: list[tuple[int, torch.Tensor]] = []
        for item in items:
            if item.mode == LUMA_KEYFRAME_MODE_SECONDS:
                if item.value > duration_seconds:
                    raise ValueError(
                        f"Keyframe position {item.value:g}s is past the end of the {duration} video; "
                        f"use 0-{duration_seconds:g}s (or switch the keyframe to fraction mode)."
                    )
                idx = round(item.value * 24)
            else:
                idx = round(item.value * maxframe)
            placed.append((max(0, min(maxframe, idx)), item.image))
        placed.sort(key=lambda p: p[0])
        indexes = [idx for idx, _ in placed]
        for a, b in zip(indexes, indexes[1:]):
            if a == b:
                raise ValueError(
                    f"Two keyframes resolve to the same output frame ({a}) for a {duration} video "
                    f"(valid range 0-{maxframe}); give each keyframe a distinct position."
                )
        refs: list[Luma2ImageRef] = []
        for _, image in placed:
            url = await upload_image_to_comfyapi(cls, image, mime_type="image/png")

View on GitHub (pinned to 1c6d8d45b3)

Solutions

  1. Lower the offending keyframe's position to within 0-{duration}s (≤5.0 or ≤10.0).
  2. Or switch that keyframe to fraction mode, where positions are relative to the video length and always valid.
  3. Re-check all keyframe positions after changing the duration widget.
Defensive patterns

Strategy: validation

Validate before calling

duration_seconds = 5.0 if duration == "5s" else 10.0
for item in items:
    if item.mode == "seconds" and item.value > duration_seconds:
        raise ValueError(f"Keyframe at {item.value:g}s exceeds {duration_seconds:g}s video")

Prevention

When it happens

Trigger: A chained keyframe node with mode=seconds and value > 5 (for duration '5s') or > 10 (for '10s'), e.g. 7.5s on a 5s video.

Common situations: User switches the video duration from 10s to 5s but leaves keyframe positions unchanged; keyframe values copied from a longer-video workflow; off-by-boundary values like exactly duration+0.1.

Related errors


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