{"record":{"id":"7c36d92717d294ff","repo":"Comfy-Org/ComfyUI","slug":"provide-only-one-of-last-frame-or-last-frame-asset","errorCode":null,"errorMessage":"Provide only one of last_frame or last_frame_asset_id, not both.","messagePattern":"Provide only one of last_frame or last_frame_asset_id, not both\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"comfy_api_nodes/nodes_bytedance.py","lineNumber":2503,"sourceCode":"        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)\n        else:\n            # The 1080p FLF stretch fix (pre-size frames to a supported pixel pair + submit ratio=\"adaptive\")","sourceCodeStart":2485,"sourceCodeEnd":2521,"githubUrl":"https://github.com/Comfy-Org/ComfyUI/blob/1c6d8d45b3693bfbb32385b410d813a7fd6be216/comfy_api_nodes/nodes_bytedance.py#L2485-L2521","documentation":"Same mutual-exclusion rule as the first frame, applied to the optional last frame: the node accepts last_frame as either an image tensor or an asset id string (last_frame_asset_id), but not both. The last frame is optional, so emptying one of the two inputs fully resolves the conflict.","triggerScenarios":"Calling the keyframe node with last_frame wired AND a non-empty last_frame_asset_id.","commonSituations":"Leftover asset id from a previous run kept in the widget after switching to direct image input.","solutions":["Clear the last_frame_asset_id widget if feeding the image directly.","Or disconnect the last_frame image to use the asset id."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if last_frame is not None and last_frame_asset_id.strip():\n    raise ValueError(\"pass only one of last_frame / last_frame_asset_id\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["The last frame is optional: empty both sides if unused.","Never leave a stale asset id in the widget when wiring the image input."],"tags":["bytedance","seedance","validation","input-conflict","api-nodes"],"backgroundTag":null,"analyzedSha":"1c6d8d45b3693bfbb32385b410d813a7fd6be216","analyzedAt":"2026-08-14T19:37:18.893Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}