{"record":{"id":"a291311f091e6610","repo":"Comfy-Org/ComfyUI","slug":"either-first-frame-or-first-frame-asset-id-is-requ","errorCode":null,"errorMessage":"Either first_frame or first_frame_asset_id is required.","messagePattern":"Either first_frame or first_frame_asset_id is required\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"comfy_api_nodes/nodes_bytedance.py","lineNumber":2501,"sourceCode":"        cls,\n        model: dict,\n        seed: int,\n        watermark: bool,\n        first_frame: Input.Image | None = None,\n        last_frame: Input.Image | None = None,\n        first_frame_asset_id: str = \"\",\n        last_frame_asset_id: str = \"\",\n    ) -> IO.NodeOutput:\n        validate_string(model[\"prompt\"], strip_whitespace=True, min_length=1)\n        model_id = SEEDANCE_MODELS[model[\"model\"]]\n\n        first_frame_asset_id = first_frame_asset_id.strip()\n        last_frame_asset_id = last_frame_asset_id.strip()\n\n        if first_frame is not None and first_frame_asset_id:\n            raise ValueError(\"Provide only one of first_frame or first_frame_asset_id, not both.\")\n        if first_frame is None and not first_frame_asset_id:\n            raise ValueError(\"Either first_frame or first_frame_asset_id is required.\")\n        if last_frame is not None and last_frame_asset_id:\n            raise ValueError(\"Provide only one of last_frame or last_frame_asset_id, not both.\")\n\n        if model_id == \"dreamina-seedance-2-5-260628\":\n            # 2.5 accepts ratio=\"adaptive\" only here and keeps the first frame's own aspect\n            # (a 1920x1088 frame yields 850x482, not a grid ratio), so pre-sizing the frames to a\n            # supported pixel pair would crop framing the model would otherwise have preserved.\n            request_ratio = \"adaptive\"\n            if first_frame is not None:\n                first_frame = _prepare_seedance_image(first_frame)\n            if last_frame is not None:\n                last_frame = _prepare_seedance_image(last_frame)\n        elif first_frame_asset_id or last_frame_asset_id:\n            request_ratio = model[\"ratio\"]\n            if first_frame is not None:\n                first_frame = _prepare_seedance_image(first_frame)\n            if last_frame is not None:\n                last_frame = _prepare_seedance_image(last_frame)","sourceCodeStart":2483,"sourceCodeEnd":2519,"githubUrl":"https://github.com/Comfy-Org/ComfyUI/blob/1c6d8d45b3693bfbb32385b410d813a7fd6be216/comfy_api_nodes/nodes_bytedance.py#L2483-L2519","documentation":"The keyframe Seedance node requires a first frame to anchor the generation; neither the first_frame image input nor the first_frame_asset_id string was provided. Unlike the general reference node, this i2v-style path cannot run text-only, so the node fails fast before uploading or polling anything.","triggerScenarios":"Calling the first/last-frame node with first_frame left unwired and an empty/whitespace first_frame_asset_id string.","commonSituations":"Converting a t2v workflow to the keyframe node without wiring the frame; asset id typo that strips to empty; partially copied node configs.","solutions":["Connect an image to first_frame.","Or paste a valid uploaded asset id into first_frame_asset_id (from the asset upload node's output)."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if first_frame is None and not first_frame_asset_id.strip():\n    raise ValueError(\"first frame required: wire first_frame or set first_frame_asset_id\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always wire a first frame; this node has no text-only path.","For pure text-to-video use the t2v Seedance node instead."],"tags":["bytedance","seedance","validation","missing-input","api-nodes"],"backgroundTag":null,"analyzedSha":"1c6d8d45b3693bfbb32385b410d813a7fd6be216","analyzedAt":"2026-08-14T19:37:18.893Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}