{"record":{"id":"f03df4a6e5d58ce0","repo":"calesthio/OpenMontage","slug":"spec-operation-requires-at-least-one-source-i","errorCode":null,"errorMessage":"{spec['operation']} requires at least one source image","messagePattern":"(.+?) requires at least one source image","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"tools/graphics/atlas_image.py","lineNumber":167,"sourceCode":"        if style == \"star\":\n            payload[\"size\"] = f\"{width}*{height}\"\n        elif style == \"x\":\n            payload[\"size\"] = f\"{width}x{height}\"\n        elif style == \"ratio\":\n            payload[\"aspect_ratio\"] = inputs.get(\"aspect_ratio\") or atlas_client.aspect_ratio_from_size(\n                width, height, _COMMON_RATIOS\n            )\n        elif style == \"tier\":\n            payload[\"size\"] = inputs.get(\"resolution\", \"auto\")\n\n        images = list(inputs.get(\"image_urls\") or [])\n        if inputs.get(\"image_url\"):\n            images.insert(0, inputs[\"image_url\"])\n        media_style = spec[\"media_style\"]\n        if media_style == \"images\":\n            maximum = int(spec[\"max_images\"])\n            if not images:\n                raise ValueError(f\"{spec['operation']} requires at least one source image\")\n            if len(images) > maximum:\n                raise ValueError(f\"{model} accepts at most {maximum} source images\")\n            payload[\"images\"] = images\n        elif media_style == \"image\":\n            if len(images) != 1:\n                raise ValueError(\"layer decomposition requires exactly one source image\")\n            payload[\"image\"] = images[0]\n\n        for field in spec.get(\"optional_fields\", ()):\n            if inputs.get(field) is not None:\n                payload[field] = inputs[field]\n        if inputs.get(\"output_format\") and inputs[\"output_format\"] != \"default\":\n            payload[\"output_format\"] = inputs[\"output_format\"]\n\n        extra = inputs.get(\"extra_params\")\n        if isinstance(extra, dict):\n            payload.update(extra)\n        return payload","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/calesthio/OpenMontage/blob/95e1c3d0ab93482159818560f6a8c8e866b9139f/tools/graphics/atlas_image.py#L149-L185","documentation":"ValueError raised in _build_payload when a multi-image ('images' media_style) model receives zero source images. The list built from image_urls plus an optional leading image_url is empty, so the operation cannot run — these models are image-to-image/edit style and have no zero-input mode.","triggerScenarios":"Calling an edit/reference model with neither image_urls nor image_url in inputs, e.g. passing only a prompt, or passing image_urls=None/empty list (falsy values are dropped by `or []`).","commonSituations":"Reusing a text-to-image call shape for an edit model, forgetting to upload/attach reference images, or upstream code that conditionally sets image_urls and skips it when the list is empty.","solutions":["Provide at least one accessible image URL via image_urls (or image_url) matching the model's expected input.","If you wanted pure text-to-image, select a generate-mode model instead (see the family/route validation).","Validate non-empty image inputs before calling: `assert inputs.get('image_urls')`.","Ensure URLs are publicly reachable http(s) URLs the Atlas API can fetch."],"exampleFix":"# before\ninputs = {\"model\": \"<edit-model>\", \"prompt\": \"restyle\"}  # no images -> ValueError\n\n# after\ninputs = {\"model\": \"<edit-model>\", \"prompt\": \"restyle\", \"image_urls\": [uploaded_url]}","handlingStrategy":"validation","validationCode":"images = list(inputs.get(\"image_urls\") or [])\nif inputs.get(\"image_url\"):\n    images.insert(0, inputs[\"image_url\"])\nassert images, \"edit/reference models require at least one source image URL\"","typeGuard":"def has_source_images(inputs: dict) -> bool:\n    return bool(inputs.get(\"image_urls\") or inputs.get(\"image_url\"))","tryCatchPattern":"try:\n    result = tool.run(inputs)\nexcept ValueError as e:\n    if \"requires at least one source image\" in str(e):\n        raise ValueError(\"Upload an image first and pass its URL via image_urls\") from e\n    raise","preventionTips":["Check image inputs are present and non-empty before calling edit-family models.","Distinguish text-to-image and image-to-image flows in your orchestration layer.","Ensure uploaded image URLs are reachable by the Atlas API before submission."],"tags":["atlas-cloud","image","input-validation","edit"],"backgroundTag":null,"analyzedSha":"95e1c3d0ab93482159818560f6a8c8e866b9139f","analyzedAt":"2026-08-15T06:31:20.014Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}