{"record":{"id":"fb93aee90a9b908d","repo":"Comfy-Org/ComfyUI","slug":"at-least-one-of-first-image-and-last-image-require","errorCode":null,"errorMessage":"At least one of first_image and last_image requires an input.","messagePattern":"At least one of first_image and last_image requires an input\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"comfy_api_nodes/nodes_luma.py","lineNumber":561,"sourceCode":"            is_api_node=True,\n            price_badge=PRICE_BADGE_VIDEO,\n        )\n\n    @classmethod\n    async def execute(\n        cls,\n        prompt: str,\n        model: str,\n        resolution: str,\n        duration: str,\n        loop: bool,\n        seed,\n        first_image: torch.Tensor = None,\n        last_image: torch.Tensor = None,\n        luma_concepts: LumaConceptChain = None,\n    ) -> IO.NodeOutput:\n        if first_image is None and last_image is None:\n            raise Exception(\"At least one of first_image and last_image requires an input.\")\n        keyframes = await cls._convert_to_keyframes(first_image, last_image)\n        duration = duration if model != LumaVideoModel.ray_1_6 else None\n        resolution = resolution if model != LumaVideoModel.ray_1_6 else None\n        response_api = await sync_op(\n            cls,\n            ApiEndpoint(path=\"/proxy/luma/generations\", method=\"POST\"),\n            response_model=LumaGeneration,\n            data=LumaGenerationRequest(\n                prompt=prompt,\n                model=model,\n                aspect_ratio=LumaAspectRatio.ratio_16_9,  # ignored, but still needed by the API for some reason\n                resolution=resolution,\n                duration=duration,\n                loop=loop,\n                keyframes=keyframes,\n                concepts=luma_concepts.create_api_model() if luma_concepts else None,\n            ),\n        )","sourceCodeStart":543,"sourceCodeEnd":579,"githubUrl":"https://github.com/Comfy-Org/ComfyUI/blob/1c6d8d45b3693bfbb32385b410d813a7fd6be216/comfy_api_nodes/nodes_luma.py#L543-L579","documentation":"Raised by the legacy Luma keyframe video node (comfy_api_nodes/nodes_luma.py:561) when both first_image and last_image are None. The Luma generations API requires at least one keyframe image to anchor the video, so the node fails fast before calling _convert_to_keyframes or the remote endpoint.","triggerScenarios":"Executing LumaVideoNode (or the image-to-video variant) with neither first_image nor last_image wired, e.g. relying on prompt-only generation against a node whose schema demands a start or end frame.","commonSituations":"User copies a text-to-video workflow into the image-to-video node, or disconnects an image input during graph editing and re-runs the queue.","solutions":["Connect an image to first_image (start frame) or last_image (end frame).","If you want prompt-only Luma video, use the dedicated text-to-video Luma node instead.","Check for accidentally disconnected edges after graph refactors."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if first_image is None and last_image is None:\n    raise ValueError(\"Wire a start or end frame, or use the Luma text-to-video node\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pick the node variant (text-to-video vs image-to-video) based on whether you have frames.","After graph edits, re-verify required edges into Luma image-to-video nodes."],"tags":["luma","keyframes","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"}