affaan-m/ECC · error · FalError

views must include 'input_image_url' (the front view)

Error message

views must include 'input_image_url' (the front view)

What it means

FalError raised by image_to_3d() when a `views` dict is supplied but filtered to no 'input_image_url' entry — the front-view image is mandatory for multi-view 3D generation. Non-VIEW_FIELDS keys and empty values are stripped before the check.

Solutions

  1. Include 'input_image_url' pointing at the front-view image URL in the views dict
  2. Check the key spelling and that the value is a non-empty URL string
  3. If the front view upload failed, re-upload it via falapi.upload() before calling
  4. If you only have one image, pass it via image_url and omit views

Example fix

// before
falapi.image_to_3d(views={"back_image_url": back})  # FalError
// after
falapi.image_to_3d(views={"input_image_url": front, "back_image_url": back})
Defensive patterns

Strategy: validation

Validate before calling

def validate_views(views: dict) -> bool:
    return bool(views) is False or bool(views.get("input_image_url"))

Try / catch

try:
    mesh = falapi.image_to_3d(image_url=fallback, views=views)
except falapi.FalError as e:
    if "input_image_url" in str(e):
        print("views dict must contain a non-empty 'input_image_url'")

Prevention

When it happens

Trigger: image_to_3d(image_url=..., views={...}) where views contains only back/left/right keys, or where the input_image_url value is empty/None so it is filtered out before validation.

Common situations: Caller builds the views dict from per-angle URLs and the front image failed to upload; dict keys misspelled (e.g. 'front_image_url'); empty-string URL passed through.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/e272c2bfdcd94f8c. Report an issue: GitHub.

Appendix: source

Thrown at skills/taste-distillation/scripts/taste/falapi.py:512

    ``{"input_image_url": front, "back_image_url": back}``. Passing a bare
    list assigns images to :data:`VIEW_FIELDS` in order, which is a guess and
    is only correct if the caller actually sorted them that way; a wrong angle
    label is worse than omitting the view entirely, because the model trusts
    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:

View on GitHub (pinned to 8321021c54)