affaan-m/ECC · error · FalError

no image URL in response from

Error message

no image URL in response from {ENDPOINTS['text_to_image']}

What it means

FalError raised by text_to_image() after submit() returns a result from which parse_urls() extracts no image URLs. It names the failing endpoint so you know which model's response was malformed. One image is requested (num_images=1), so an empty URL list means the provider did not return the expected output.

Solutions

  1. Log the raw result dict to inspect what the endpoint actually returned
  2. Rephrase the prompt if a content policy rejection is suspected and retry
  3. Check the fal.ai model page for the endpoint's current response schema and update parsing
  4. Wrap submit/parse in a retry for transient provider failures

Example fix

// before
urls = falapi.text_to_image(prompt)  # FalError: no image URL in response
// after
try:
    urls = falapi.text_to_image(prompt)
except falapi.FalError:
    result = falapi.submit(falapi.ENDPOINTS["text_to_image"], {"prompt": prompt, "num_images": 1})
    raise RuntimeError(f"text_to_image returned no URLs; keys={list(result) if isinstance(result, dict) else type(result)}")
Defensive patterns

Strategy: retry

Validate before calling

result = falapi.submit(falapi.ENDPOINTS["text_to_image"], {"prompt": prompt, "num_images": 1})
assert falapi.parse_urls(result), f"no image URLs; keys={list(result) if isinstance(result, dict) else type(result)}"

Try / catch

try:
    urls = falapi.text_to_image(prompt)
except falapi.FalError:
    prompt = sanitize_prompt(prompt)  # may have tripped content policy
    urls = falapi.text_to_image(prompt)

Prevention

When it happens

Trigger: text_to_image(prompt, ...) where the fal response lacks its image output field — provider response-shape change, content-policy rejection returning an error object, or model failure.

Common situations: Prompt tripped a provider safety filter and the endpoint returned no images; fal.ai updated the model's output schema; transient provider error surfaced as an empty result.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


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

Appendix: source

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

def quantize_duration(duration: float, lo: int = 3, hi: int = 12) -> int:
    """Round a planned shot length onto the video model's supported grid."""
    return int(max(lo, min(hi, round(float(duration)))))


def text_to_image(
    prompt: str,
    image_refs: list[str] | None = None,
    *,
    timeout: int = 300,
) -> list[str]:
    """Generate stills, optionally conditioned on reference images."""
    payload: dict[str, Any] = {"prompt": prompt, "num_images": 1}
    if image_refs:
        payload["image_urls"] = list(image_refs)
    result = submit(ENDPOINTS["text_to_image"], payload, timeout)
    urls = parse_urls(result)
    if not urls:
        raise FalError(f"no image URL in response from {ENDPOINTS['text_to_image']}")
    return urls


def extract_frame(video_url: str, timestamp: float, *, timeout: int = 300) -> str:
    """Pull a single frame out of a hosted video. Returns the image URL."""
    payload = {"video_url": video_url, "timestamp": round(float(timestamp), 3)}
    result = submit(ENDPOINTS["extract_frame"], payload, timeout)
    return first_url(result, ENDPOINTS["extract_frame"])


def compose(tracks: list[dict], *, timeout: int = 900) -> str:
    """Composite timeline tracks into one video. Returns the output URL.

    ``tracks`` is passed straight through so the caller owns the timeline
    shape; the ffmpeg-api track schema is another default worth verifying
    before a live run.
    """
    result = submit(ENDPOINTS["compose"], {"tracks": tracks}, timeout)

View on GitHub (pinned to 8321021c54)