{"record":{"id":"09ab1fdbf53327fc","repo":"calesthio/OpenMontage","slug":"this-gemini-route-requires-at-least-one-reference","errorCode":null,"errorMessage":"This Gemini route requires at least one reference image","messagePattern":"This Gemini route requires at least one reference image","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"tools/video/atlas_video.py","lineNumber":245,"sourceCode":"        style = spec[\"media_style\"]\n        image = inputs.get(\"image_url\") or inputs.get(\"reference_image_url\")\n        last_image = inputs.get(\"last_image_url\") or inputs.get(\"end_image_url\")\n        images = list(inputs.get(\"reference_images\") or [])\n        videos = list(inputs.get(\"reference_videos\") or [])\n        audios = list(inputs.get(\"reference_audios\") or [])\n        video = inputs.get(\"video_url\") or inputs.get(\"reference_video_url\")\n\n        if style in {\"seedance_image\", \"gemini_image\", \"h3_image\"}:\n            if not image:\n                raise ValueError(\"image_to_video requires image_url, image_path, or reference_image_path\")\n            payload[\"image\"] = image\n            if last_image:\n                payload[\"last_image\" if style == \"seedance_image\" else \"end_image\"] = last_image\n        elif style == \"gemini_images\":\n            if image and not images:\n                images = [image]\n            if not images:\n                raise ValueError(\"This Gemini route requires at least one reference image\")\n            payload[\"images\"] = images\n        elif style == \"seedance_references\":\n            if image and not images:\n                images = [image]\n            if not (images or videos or (audios and spec[\"family\"] == \"bytedance/seedance-2.5\")):\n                raise ValueError(\"reference_to_video requires supported reference media for the selected model\")\n            limits = spec[\"media_limits\"]\n            if len(images) > limits[\"images\"] or len(videos) > limits[\"videos\"] or len(audios) > limits[\"audios\"]:\n                raise ValueError(\n                    f\"{model} accepts at most {limits['images']} images, {limits['videos']} videos, \"\n                    f\"and {limits['audios']} audio references\"\n                )\n            if images:\n                payload[\"reference_images\"] = images\n            if videos:\n                payload[\"reference_videos\"] = videos\n            if audios:\n                payload[\"reference_audios\"] = audios","sourceCodeStart":227,"sourceCodeEnd":263,"githubUrl":"https://github.com/calesthio/OpenMontage/blob/95e1c3d0ab93482159818560f6a8c8e866b9139f/tools/video/atlas_video.py#L227-L263","documentation":"Raised in _build_payload for media_style=='gemini_images' when the inputs contain no reference images at all. This Gemini route requires at least one image; a lone image_url is promoted into the images list, but if both image_url and reference_images are absent the payload cannot be built.","triggerScenarios":"Calling the gemini_images model with only a text prompt; supplying reference_images as an empty list plus no image_url; misspelling the key (e.g. 'ref_images').","commonSituations":"Using a multi-reference Gemini route as if it were plain text-to-video; forgetting to attach the style/reference frames when porting a workflow from another provider; passing image paths under a key that was uploaded but not forwarded.","solutions":["Pass reference_images (list) or a single image_url/reference_image_path — the lone image is auto-promoted to the list","Verify the list is non-empty after your upload/normalization step before calling the tool","If you actually wanted pure text-to-video, switch to a model whose spec supports it"],"exampleFix":"# before\ninputs = {'model':'google/gemini-image','prompt':'a cat in the style of the frames'}\n\n# after\ninputs = {'model':'google/gemini-image','prompt':'a cat in the style of the frames','reference_images':['assets/frame1.png','assets/frame2.png']}","handlingStrategy":"validation","validationCode":"images = list(inputs.get('reference_images') or [])\nif inputs.get('image_url') and not images:\n    images = [inputs['image_url']]\nif not images:\n    raise ValueError('gemini_images route needs >=1 reference image')\ninputs['reference_images'] = images","typeGuard":"def gemini_images_ready(inputs: dict) -> bool:\n    return bool(inputs.get('reference_images') or inputs.get('image_url') or inputs.get('reference_image_url'))","tryCatchPattern":"try:\n    result = atlas_video.run(inputs=inputs)\nexcept ValueError as e:\n    if 'at least one reference image' in str(e):\n        raise SystemExit('attach reference frames for this Gemini route') from e\n    raise","preventionTips":["Do the lone-image-to-list promotion in your own code so the invariant is explicit","Assert non-empty media lists right after your upload/normalization stage","Reserve this model for style/reference work; use a t2v model for prompt-only runs"],"tags":["atlas-cloud","gemini","video-generation","validation"],"backgroundTag":null,"analyzedSha":"95e1c3d0ab93482159818560f6a8c8e866b9139f","analyzedAt":"2026-08-15T06:31:20.014Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}