affaan-m/ECC · error · FalError
image_to_3d needs at least one image
Error message
image_to_3d needs at least one image
What it means
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.
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
Example fix
// before urls = [u for u in candidate_urls if keep(u)] # came back empty falapi.image_to_3d(image_url=urls) # FalError // after urls = [u for u in candidate_urls if keep(u)] assert urls, "image_to_3d: no candidate images survived filtering" falapi.image_to_3d(image_url=urls)
Defensive patterns
Strategy: validation
Validate before calling
images = image_url if isinstance(image_url, list) else [image_url]
if not views and not any(images):
raise ValueError("image_to_3d requires at least one image") Try / catch
try:
mesh = falapi.image_to_3d(image_url=urls)
except falapi.FalError as e:
if "at least one image" in str(e):
print("Upstream produced no images; fix extraction step") Prevention
- 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
When it happens
Trigger: 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).
Common situations: Upstream frame-extraction returned no images; caller passed an empty list after filtering failed uploads; forgot to pass image_url entirely.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- merge_videos() needs at least one video URL
- views must include 'input_image_url' (the front view)
- application bundle differs from its bound evidence
- At least one video is required
- cannot upload, file does not exist
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/b814ea8c70a2eb7a.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-distillation/scripts/taste/falapi.py:516
it. When in doubt, send one image.
``pbr`` requests physically-based maps (metallic, roughness, normal). Without
them the mesh lights like painted cardboard in Blender, which defeats the
point of minting it. It is ignored when ``geometry_only`` is set.
Note the endpoint's own input guidance: simple background, single object,
object filling >50% of frame. Busy reference stills - collages, wide shots,
anything with several subjects - produce garbage meshes. Generate a clean
single-object plate first if the pack's stills are not that.
"""
if views:
payload: dict = {k: v for k, v in views.items() if k in VIEW_FIELDS and v}
if "input_image_url" not in payload:
raise FalError("views must include 'input_image_url' (the front view)")
else:
urls = [image_url] if isinstance(image_url, str) else list(image_url)
if not urls:
raise FalError("image_to_3d needs at least one image")
payload = {f: u for f, u in zip(VIEW_FIELDS, urls[:len(VIEW_FIELDS)])}
payload["generate_type"] = "Geometry" if geometry_only else "Normal"
if not geometry_only:
payload["enable_pbr"] = bool(pbr)
if face_count:
# Endpoint range is 40k-1.5M; clamp rather than let it 422.
payload["face_count"] = int(max(40_000, min(1_500_000, face_count)))
result = submit(ENDPOINTS["image_to_3d"], payload, timeout)
return _mesh_url(result, ENDPOINTS["image_to_3d"])
def text_to_3d(prompt: str, *, pbr: bool = True, timeout: int = 900) -> str:
"""Mint a textured GLB from a description. Returns the mesh URL.
The complement to image_to_3d: use it for props the reference *implies*
but never shows cleanly enough to lift - the pack's spec describes theView on GitHub (pinned to 8321021c54)