affaan-m/ECC · error · FalError
no URL in provider response; response shape may have…
Error message
no URL in provider response; response shape may have changed (provider payload omitted)
What it means
FalError raised by first_url() when parse_urls() finds no URL in a provider result. It guards against fal.ai response-shape changes: if the expected nested URL is missing, the library refuses to return a bogus value and notes the payload is omitted. Called by _mesh_url, retopologize, split_parts, images_to_video, reference_to_video, extract_frame.
Solutions
- Log the raw result dict (locally, not in shared output) to inspect the actual response shape
- Update the parse/expected key to match the current provider response schema
- Check fal.ai model page/changelog for the endpoint's current output format
- Guard upstream: verify the generation job succeeded before extracting the URL
Example fix
// before
url = falapi.first_url(result, ENDPOINTS["compose"]) # FalError: no URL in provider response
// after
urls = falapi.parse_urls(result)
if not urls:
raise RuntimeError(f"no URL from compose; result keys: {list(result) if isinstance(result, dict) else type(result)}")
url = urls[0] Defensive patterns
Strategy: try-catch
Validate before calling
urls = falapi.parse_urls(result)
if not urls:
raise RuntimeError(f"no URL in result; type={type(result)}, keys={list(result) if isinstance(result, dict) else 'n/a'}") Type guard
def has_url(result) -> bool:
return bool(falapi.parse_urls(result)) Try / catch
try:
url = falapi.first_url(result, endpoint)
except falapi.FalError:
dump_result_keys(result) # inspect shape locally before deciding
raise Prevention
- Pin/check the fal.ai model version for each endpoint; watch changelogs for schema changes
- Inspect raw result payloads in dev before trusting first_url
- Validate generation succeeded before URL extraction
- Keep a small smoke test per endpoint that asserts URL extraction works
When it happens
Trigger: Any wrapper (e.g. extract_frame, merge_videos, text_to_3d) whose submit() result dict lacks the field where the output URL normally lives — provider API updated, model returned an error object instead of output, or the job produced no artifacts.
Common situations: fal.ai upgraded an endpoint and renamed the output key; the model failed silently and returned a partial/empty payload; passing a result from the wrong endpoint to first_url.
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
- fal call failed after one attempt; job acceptance may be…
- no image URL in response from
- fal call failed after one attempt; job acceptance may be…
- fal upload failed; provider details omitted
- fal upload failed; provider details omitted
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/769f0dc0870d1e0b.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-distillation/scripts/taste/falapi.py:370
elif isinstance(node, dict):
if isinstance(node.get("url"), str):
found.append(node["url"])
for k, v in node.items():
if k != "url":
walk(v)
elif isinstance(node, (list, tuple)):
for v in node:
walk(v)
walk(result)
seen: set[str] = set()
return [u for u in found if not (u in seen or seen.add(u))]
def first_url(result: Any, endpoint: str) -> str:
urls = parse_urls(result)
if not urls:
raise FalError(
"no URL in provider response; response shape may have changed "
"(provider payload omitted)"
)
return urls[0]
def _mesh_url(result: Any, endpoint: str) -> str:
"""The GLB out of a 3D response, addressed by key rather than by position.
``first_url`` would work only as long as ``model_glb`` happens to be the
first URL-bearing key in the response. It is today; the response also
carries a ``thumbnail`` PNG and a ``model_urls`` block with obj/fbx/mtl,
so a key reordering upstream would quietly start returning a preview image
where a mesh is expected - and a preview image downloads fine, so nothing
would fail until Blender refused to open it.
"""
if isinstance(result, dict):
for path in (("model_glb", "url"), ("model_urls", "glb", "url"),View on GitHub (pinned to 8321021c54)