{"record":{"id":"695562af4dbce053","repo":"Comfy-Org/ComfyUI","slug":"two-keyframes-resolve-to-the-same-output-frame-a","errorCode":null,"errorMessage":"Two keyframes resolve to the same output frame ({a}) for a {duration} video (valid range 0-{maxframe}); give each keyframe a distinct position.","messagePattern":"Two keyframes resolve to the same output frame \\((.+?)\\) for a (.+?) video \\(valid range 0-(.+?)\\); give each keyframe a distinct position\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"comfy_api_nodes/nodes_luma.py","lineNumber":1261,"sourceCode":"        # 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\")\n            refs.append(Luma2ImageRef(url=url))\n        request = Luma2GenerationRequest(\n            prompt=prompt,\n            model=\"ray-3.2\",\n            type=\"video\",\n            video=Luma2VideoOptions(resolution=resolution, duration=duration, keyframes=refs, keyframe_indexes=indexes),\n        )\n        return await _ray32_generate(cls, request)\n\n\nclass LumaRay32VideoEditNode(IO.ComfyNode):\n    @classmethod","sourceCodeStart":1243,"sourceCodeEnd":1279,"githubUrl":"https://github.com/Comfy-Org/ComfyUI/blob/1c6d8d45b3693bfbb32385b410d813a7fd6be216/comfy_api_nodes/nodes_luma.py#L1243-L1279","documentation":"Raised by the Luma Ray 3.2 keyframe video node (comfy_api_nodes/nodes_luma.py:1261) when two keyframes resolve (after rounding to 24fps frame indexes and clamping) to the same output frame. The upstream API requires distinct keyframe_indexes, so duplicates are rejected before upload.","triggerScenarios":"Two keyframes with positions that round to the same frame index: e.g. 2.00s and 2.04s on a 5s video (both → frame 48), or two fraction-mode keyframes at 0.5 in a short video; clamping also merges any out-of-range positions at frame 0 or maxframe.","commonSituations":"User adds keyframes at near-identical timestamps; fraction values like 0.33/0.34 rounding together on 5s (120 frames); duplicate chain entries.","solutions":["Spread the two colliding keyframes apart by at least 1/24s (one frame).","Check the reported frame index {a} against each keyframe's position to find the pair.","Remove redundant keyframes at effectively the same timestamp."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"maxframe = 120 if duration == \"5s\" else 240\nidxs = sorted(\n    max(0, min(maxframe, round(i.value * 24 if i.mode == \"seconds\" else i.value * maxframe)))\n    for i in items\n)\nif len(set(idxs)) != len(idxs):\n    raise ValueError(f\"Keyframe frame collision at frame {[f for f in idxs if idxs.count(f) > 1][0]}\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Space keyframes at least 1/24s apart; remember positions are rounded to integer frame indexes.","Duplicate positions also arise from clamping — keep positions strictly inside 0..maxframe."],"tags":["luma","ray-3-2","keyframes","frame-collision","input-validation","comfy-api-nodes"],"backgroundTag":null,"analyzedSha":"1c6d8d45b3693bfbb32385b410d813a7fd6be216","analyzedAt":"2026-08-14T19:37:18.893Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}