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
When image_to_3d is called without a views dict, it builds the image list from image_url (a single string or an iterable). If that list ends up empty, there is no image to send to the 3D generation endpoint and the library raises FalError before submitting.
Solutions
- Pass at least one non-empty image URL via image_url
- If passing an iterable, check its length is >= 1 before calling
- If intending multi-view input, pass a views dict containing 'input_image_url' instead
Example fix
# before
image_to_3d(urls) # urls may be []
# after
if not urls:
raise ValueError('need at least one image for image_to_3d')
image_to_3d(urls) Defensive patterns
Strategy: validation
Validate before calling
urls = [image_url] if isinstance(image_url, str) else list(image_url or [])
if not urls:
raise ValueError('image_to_3d requires at least one image URL') Type guard
def has_images(image_url) -> bool:
if isinstance(image_url, str): return bool(image_url)
return bool(image_url) Prevention
- Assert the image URL variable is populated before calling image_to_3d
- Propagate failures from earlier generation steps instead of silently passing None/[]
- Don't pass views={} expecting a fallback — it is falsy and hits this branch
- Validate URLs are non-empty https strings at pipeline boundaries
When it happens
Trigger: image_to_3d(None) or image_to_3d('') or image_to_3d([]) — any call where views is falsy and image_url resolves to an empty list.
Common situations: A variable holding the image URL was never populated because an earlier generation step failed silently; passing an empty list after filtering out None entries from a multi-image pipeline; accidentally passing views={} which is falsy and falls into the else branch.
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)
- at least one explicit seed is required
- At least one guided harness must be selected
- at least one non-empty
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/e25ab8e8cb2e087e.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-application/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)