{"record":{"id":"1908294c04c99ed7","repo":"Comfy-Org/ComfyUI","slug":"keyframe-position-item-value-g-s-is-past-the-end","errorCode":null,"errorMessage":"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).","messagePattern":"Keyframe position (.+?)s is past the end of the (.+?) video; use 0-(.+?)s \\(or switch the keyframe to fraction mode\\)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"comfy_api_nodes/nodes_luma.py","lineNumber":1249,"sourceCode":"    ) -> IO.NodeOutput:\n        validate_string(prompt, strip_whitespace=True, min_length=1, max_length=6000)\n        items = keyframes.items if keyframes is not None else []\n        if len(items) < 2:\n            raise ValueError(\n                \"Connect at least 2 Luma Ray 3.2 Keyframe nodes \"\n                \"(use Luma Ray 3.2 Image to Video for a single start/end frame).\"\n            )\n        if len(items) > 64:\n            raise ValueError(f\"Ray 3.2 supports at most 64 keyframes; got {len(items)}.\")\n        maxframe = 120 if duration == \"5s\" else 240\n        duration_seconds = maxframe / 24  # 5.0 or 10.0\n        # Resolve each keyframe to an output-frame index, then order by position\n        # (so the user can chain keyframes in any order — the position is what places them)\n        placed: list[tuple[int, torch.Tensor]] = []\n        for item in items:\n            if item.mode == LUMA_KEYFRAME_MODE_SECONDS:\n                if item.value > duration_seconds:\n                    raise ValueError(\n                        f\"Keyframe position {item.value:g}s is past the end of the {duration} video; \"\n                        f\"use 0-{duration_seconds:g}s (or switch the keyframe to fraction mode).\"\n                    )\n                idx = round(item.value * 24)\n            else:\n                idx = round(item.value * maxframe)\n            placed.append((max(0, min(maxframe, idx)), item.image))\n        placed.sort(key=lambda p: p[0])\n        indexes = [idx for idx, _ in placed]\n        for a, b in zip(indexes, indexes[1:]):\n            if a == b:\n                raise ValueError(\n                    f\"Two keyframes resolve to the same output frame ({a}) for a {duration} video \"\n                    f\"(valid range 0-{maxframe}); give each keyframe a distinct position.\"\n                )\n        refs: list[Luma2ImageRef] = []\n        for _, image in placed:\n            url = await upload_image_to_comfyapi(cls, image, mime_type=\"image/png\")","sourceCodeStart":1231,"sourceCodeEnd":1267,"githubUrl":"https://github.com/Comfy-Org/ComfyUI/blob/1c6d8d45b3693bfbb32385b410d813a7fd6be216/comfy_api_nodes/nodes_luma.py#L1231-L1267","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Lower the offending keyframe's position to within 0-{duration}s (≤5.0 or ≤10.0).","Or switch that keyframe to fraction mode, where positions are relative to the video length and always valid.","Re-check all keyframe positions after changing the duration widget."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"duration_seconds = 5.0 if duration == \"5s\" else 10.0\nfor item in items:\n    if item.mode == \"seconds\" and item.value > duration_seconds:\n        raise ValueError(f\"Keyframe at {item.value:g}s exceeds {duration_seconds:g}s video\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["After changing the duration widget, re-validate every seconds-mode keyframe position.","Prefer fraction mode for reusable templates — fractions stay valid at any duration."],"tags":["luma","ray-3-2","keyframes","duration","input-validation","comfy-api-nodes"],"backgroundTag":null,"analyzedSha":"1c6d8d45b3693bfbb32385b410d813a7fd6be216","analyzedAt":"2026-08-14T19:37:18.893Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}