{"record":{"id":"b814ea8c70a2eb7a","repo":"affaan-m/ECC","slug":"image-to-3d-needs-at-least-one-image-b814ea","errorCode":null,"errorMessage":"image_to_3d needs at least one image","messagePattern":"image_to_3d needs at least one image","errorType":"validation","errorClass":"FalError","httpStatus":null,"severity":"error","filePath":"skills/taste-distillation/scripts/taste/falapi.py","lineNumber":516,"sourceCode":"    it. When in doubt, send one image.\n\n    ``pbr`` requests physically-based maps (metallic, roughness, normal). Without\n    them the mesh lights like painted cardboard in Blender, which defeats the\n    point of minting it. It is ignored when ``geometry_only`` is set.\n\n    Note the endpoint's own input guidance: simple background, single object,\n    object filling >50% of frame. Busy reference stills - collages, wide shots,\n    anything with several subjects - produce garbage meshes. Generate a clean\n    single-object plate first if the pack's stills are not that.\n    \"\"\"\n    if views:\n        payload: dict = {k: v for k, v in views.items() if k in VIEW_FIELDS and v}\n        if \"input_image_url\" not in payload:\n            raise FalError(\"views must include 'input_image_url' (the front view)\")\n    else:\n        urls = [image_url] if isinstance(image_url, str) else list(image_url)\n        if not urls:\n            raise FalError(\"image_to_3d needs at least one image\")\n        payload = {f: u for f, u in zip(VIEW_FIELDS, urls[:len(VIEW_FIELDS)])}\n\n    payload[\"generate_type\"] = \"Geometry\" if geometry_only else \"Normal\"\n    if not geometry_only:\n        payload[\"enable_pbr\"] = bool(pbr)\n    if face_count:\n        # Endpoint range is 40k-1.5M; clamp rather than let it 422.\n        payload[\"face_count\"] = int(max(40_000, min(1_500_000, face_count)))\n\n    result = submit(ENDPOINTS[\"image_to_3d\"], payload, timeout)\n    return _mesh_url(result, ENDPOINTS[\"image_to_3d\"])\n\n\ndef text_to_3d(prompt: str, *, pbr: bool = True, timeout: int = 900) -> str:\n    \"\"\"Mint a textured GLB from a description. Returns the mesh URL.\n\n    The complement to image_to_3d: use it for props the reference *implies*\n    but never shows cleanly enough to lift - the pack's spec describes the","sourceCodeStart":498,"sourceCodeEnd":534,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-distillation/scripts/taste/falapi.py#L498-L534","documentation":"FalError raised by image_to_3d() when no `views` dict is given and the `image_url` argument yields an empty list — at least one source image is required to generate a mesh. The check happens before any payload is submitted, so nothing is charged.","triggerScenarios":"image_to_3d(image_url=[]) or image_url=None-with-no-views; also image_url being an empty iterable (e.g. a list comprehension that matched nothing).","commonSituations":"Upstream frame-extraction returned no images; caller passed an empty list after filtering failed uploads; forgot to pass image_url entirely.","solutions":["Pass at least one image: image_to_3d(image_url=\"https://...\")","If upstream produced no images, fix the extraction/upload step first","Validate the list is non-empty before calling","For multiple angles pass a list; the first len(VIEW_FIELDS) entries map to view fields"],"exampleFix":"// before\nurls = [u for u in candidate_urls if keep(u)]  # came back empty\nfalapi.image_to_3d(image_url=urls)  # FalError\n// after\nurls = [u for u in candidate_urls if keep(u)]\nassert urls, \"image_to_3d: no candidate images survived filtering\"\nfalapi.image_to_3d(image_url=urls)","handlingStrategy":"validation","validationCode":"images = image_url if isinstance(image_url, list) else [image_url]\nif not views and not any(images):\n    raise ValueError(\"image_to_3d requires at least one image\")","typeGuard":null,"tryCatchPattern":"try:\n    mesh = falapi.image_to_3d(image_url=urls)\nexcept falapi.FalError as e:\n    if \"at least one image\" in str(e):\n        print(\"Upstream produced no images; fix extraction step\")","preventionTips":["Assert the image list is non-empty right after upstream generation","Don't silently filter failed uploads into an empty list — fail loudly","Default to a single known-good image when in doubt","Log how many candidate images each pipeline stage yields"],"tags":["python","validation","argument"],"backgroundTag":"empty-required-field","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}