{"record":{"id":"be05425dfd9431c9","repo":"calesthio/OpenMontage","slug":"image-to-video-requires-image-url-image-path-or","errorCode":null,"errorMessage":"image_to_video requires image_url, image_path, or reference_image_path","messagePattern":"image_to_video requires image_url, image_path, or reference_image_path","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"tools/video/atlas_video.py","lineNumber":237,"sourceCode":"\n        resolution = inputs.get(\"resolution\", spec[\"default_resolution\"])\n        payload[\"resolution\"] = self._validate_choice(\"resolution\", resolution, spec[\"resolutions\"])\n\n        for field in spec.get(\"optional_fields\", ()):\n            if inputs.get(field) is not None:\n                payload[field] = inputs[field]\n\n        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, \"","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/calesthio/OpenMontage/blob/95e1c3d0ab93482159818560f6a8c8e866b9139f/tools/video/atlas_video.py#L219-L255","documentation":"Raised in _build_payload when the model's media_style is one of {'seedance_image','gemini_image','h3_image'} (single-image image-to-video routes) and no image source was supplied in inputs. The tool checks image_url, reference_image_url and the path-based keys that were normalized earlier; all were empty/falsy.","triggerScenarios":"Calling operation='image_to_video' with only a prompt; passing the image under a key the tool does not read (e.g. 'image', 'first_frame'); passing image_path/reference_image_path that resolved to None because the file key was misspelled upstream.","commonSituations":"Renaming input keys in a wrapper script; assuming the model auto-picks an image from a references list (it does not — single-image styles ignore reference_images); migrating a call from a multi-reference model to a single-image model without adding an explicit image field.","solutions":["Add image_url (remote) or image_path/reference_image_path (local file) to inputs","If you have a reference_images list, pass its first entry explicitly as image_url/image_path for single-image styles","Optionally add last_image_url/end_image_url if you want a final-frame constraint"],"exampleFix":"# before\ninputs = {'model':'minimax/h3','prompt':'animate this','operation':'image_to_video'}\n\n# after\ninputs = {'model':'minimax/h3','prompt':'animate this','operation':'image_to_video','image_path':'assets/hero.png'}","handlingStrategy":"validation","validationCode":"image = inputs.get('image_url') or inputs.get('image_path') or inputs.get('reference_image_path')\nif not image:\n    raise ValueError('i2v call needs image_url/image_path/reference_image_path')\nif inputs.get('image_path') and not Path(inputs['image_path']).is_file():\n    raise ValueError(f\"image file missing: {inputs['image_path']}\")","typeGuard":"def has_i2v_image(inputs: dict) -> bool:\n    return bool(inputs.get('image_url') or inputs.get('reference_image_url') or\n                inputs.get('image_path') or inputs.get('reference_image_path'))","tryCatchPattern":"try:\n    result = atlas_video.run(inputs=inputs)\nexcept ValueError as e:\n    if 'image_to_video requires' in str(e):\n        raise SystemExit('attach an image before animating it') from e\n    raise","preventionTips":["Always set an explicit image field for single-image i2v styles; never rely on reference_images","Validate local image paths exist before the call","Keep one canonical input-shape builder per operation so keys are never ad hoc"],"tags":["atlas-cloud","video-generation","image-to-video","validation"],"backgroundTag":null,"analyzedSha":"95e1c3d0ab93482159818560f6a8c8e866b9139f","analyzedAt":"2026-08-15T06:31:20.014Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}