{"record":{"id":"3facaf109d850869","repo":"affaan-m/ECC","slug":"no-image-url-in-response-from-endpoints-text-to-image-falapi","errorCode":null,"errorMessage":"no image URL in response from {ENDPOINTS['text_to_image']}","messagePattern":"no image URL in response from (.+?)","errorType":"exception","errorClass":"FalError","httpStatus":null,"severity":"error","filePath":"skills/taste-application/scripts/taste/falapi.py","lineNumber":622,"sourceCode":"def quantize_duration(duration: float, lo: int = 3, hi: int = 12) -> int:\n    \"\"\"Round a planned shot length onto the video model's supported grid.\"\"\"\n    return int(max(lo, min(hi, round(float(duration)))))\n\n\ndef text_to_image(\n    prompt: str,\n    image_refs: list[str] | None = None,\n    *,\n    timeout: int = 300,\n) -> list[str]:\n    \"\"\"Generate stills, optionally conditioned on reference images.\"\"\"\n    payload: dict[str, Any] = {\"prompt\": prompt, \"num_images\": 1}\n    if image_refs:\n        payload[\"image_urls\"] = list(image_refs)\n    result = submit(ENDPOINTS[\"text_to_image\"], payload, timeout)\n    urls = parse_urls(result)\n    if not urls:\n        raise FalError(f\"no image URL in response from {ENDPOINTS['text_to_image']}\")\n    return urls\n\n\ndef extract_frame(video_url: str, timestamp: float, *, timeout: int = 300) -> str:\n    \"\"\"Pull a single frame out of a hosted video. Returns the image URL.\"\"\"\n    payload = {\"video_url\": video_url, \"timestamp\": round(float(timestamp), 3)}\n    result = submit(ENDPOINTS[\"extract_frame\"], payload, timeout)\n    return first_url(result, ENDPOINTS[\"extract_frame\"])\n\n\ndef compose(tracks: list[dict], *, timeout: int = 900) -> str:\n    \"\"\"Composite timeline tracks into one video. Returns the output URL.\n\n    ``tracks`` is passed straight through so the caller owns the timeline\n    shape; the ffmpeg-api track schema is another default worth verifying\n    before a live run.\n    \"\"\"\n    result = submit(ENDPOINTS[\"compose\"], {\"tracks\": tracks}, timeout)","sourceCodeStart":604,"sourceCodeEnd":640,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-application/scripts/taste/falapi.py#L604-L640","documentation":"text_to_image submits a prompt to fal.ai's text-to-image endpoint and then extracts image URLs from the response. If parse_urls finds none, the library raises FalError naming the endpoint, since a successful text-to-image call must return at least one image URL.","triggerScenarios":"submit(ENDPOINTS['text_to_image'], ...) returns a payload without recognizable URL keys — e.g. the generation failed server-side while returning 200, a safety filter suppressed output, or the response schema changed for that endpoint.","commonSituations":"Prompt triggers fal.ai content moderation so no image is produced; fal.ai upgrades the model and renames the output field (e.g. images[].url); network/proxy layer returns a truncated or empty JSON body.","solutions":["Log the raw result payload to see what keys the endpoint actually returned","Rephrase the prompt to avoid safety-filter rejections and retry","Check fal.ai model changelog for the text_to_image endpoint and update parse_urls if the output schema changed","Retry the request — transient provider failures can yield empty outputs"],"exampleFix":"# before\nresult = submit(ENDPOINTS['text_to_image'], payload, timeout)\nurls = parse_urls(result)\n# after\nresult = submit(ENDPOINTS['text_to_image'], payload, timeout)\nprint('t2i payload keys:', list(result.keys()) if isinstance(result, dict) else type(result))\nurls = parse_urls(result)","handlingStrategy":"try-catch","validationCode":"if not prompt or not prompt.strip():\n    raise ValueError('prompt must be non-empty')","typeGuard":null,"tryCatchPattern":"try:\n    urls = text_to_image(prompt)\nexcept FalError:\n    urls = text_to_image(sanitized_prompt)  # rephrase to dodge safety filter","preventionTips":["Log the raw endpoint payload to diagnose empty outputs","Avoid prompt content likely to trigger fal.ai's safety filters","Retry once on empty responses before failing the pipeline","Track fal.ai model changelogs for output schema changes"],"tags":["network","api","image-generation","fal"],"backgroundTag":"unexpected-api-response-shape","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"}