{"record":{"id":"d618cae8b0d32688","repo":"affaan-m/ECC","slug":"fal-call-failed-after-one-attempt-job-acceptance-may-be-d618ca","errorCode":null,"errorMessage":"fal call failed after one attempt; job acceptance may be unknown. Reconcile provider job status before requesting another generation.","messagePattern":"fal call failed after one attempt; job acceptance may be unknown\\. Reconcile provider job status before requesting another generation\\.","errorType":"exception","errorClass":"FalError","httpStatus":null,"severity":"error","filePath":"skills/taste-application/scripts/taste/falapi.py","lineNumber":270,"sourceCode":"    \"\"\"Submit once. Ambiguous failures must be reconciled before another job.\n\n    ``max_attempts`` is retained for call compatibility but never resubmits.\n    \"\"\"\n    if is_dry_run():\n        log.info(\"[dry-run] model request (payload omitted)\")\n        return _stub(endpoint, payload)\n\n    require_live()\n    api_key()\n    try:\n        result = _fal().subscribe(\n            endpoint, arguments=payload, with_logs=False, client_timeout=timeout,\n        )\n        return result if isinstance(result, dict) else {\"output\": result}\n    except Exception:\n        # Exception strings can include keys, signed URLs and provider payloads.\n        # Do not print or chain them into caller tracebacks.\n        raise FalError(\n            \"fal call failed after one attempt; job acceptance may be unknown. \"\n            \"Reconcile provider job status before requesting another generation.\"\n        ) from None\n\n\n# ---------------------------------------------------------------------------\n# uploads (cached)\n# ---------------------------------------------------------------------------\n\n_UPLOAD_CACHE: dict[tuple[str, int, int], str] = {}\n_UPLOAD_LOCK = threading.Lock()\n\n\ndef _cache_key(path: Path) -> tuple[str, int, int]:\n    st = path.stat()\n    return (str(path.resolve()), st.st_mtime_ns, st.st_size)\n\n","sourceCodeStart":252,"sourceCodeEnd":288,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-application/scripts/taste/falapi.py#L252-L288","documentation":"falapi.submit() makes one attempt at a fal.ai job submission (fal_client call) and, on any exception, raises FalError noting that job acceptance is unknown. Provider details (which can embed keys, signed URLs, and payloads) are deliberately omitted and the exception is not chained (`from None`). Because acceptance is unknown, blindly retrying could duplicate a paid generation, so the message tells you to reconcile provider job status first.","triggerScenarios":"Any of vlm_describe, image_to_3d, text_to_3d, retopologize, split_parts, or images_to_video calling submit() when the underlying fal_client.submit call raises — network failure, provider 4xx/5xx, timeout, malformed payload, or interrupted request where the job may or may not have been accepted.","commonSituations":"Transient network drop or DNS failure mid-submit; invalid endpoint name after an API version change; payload exceeding provider limits; expired/invalid FAL_KEY causing 401; hitting a provider rate limit; server-side 500 at fal.ai; the call being killed after the request was sent but before the response arrived (the 'acceptance unknown' case).","solutions":["Check fal.ai dashboard/logs for the job (or query provider job status) before retrying — do not blindly resubmit, or you may pay for two generations.","Inspect the request payload and endpoint name for validity (correct endpoint ID, argument names, sizes within limits).","Retry the call once network/provider health is confirmed; keep the attempt count at one per invocation as the library does.","If failures persist, capture the request id/timestamp and check fal.ai status/incidents, then open a support thread; temporarily switch to --dry-run to unblock the pipeline."],"exampleFix":"# before\ntry:\n    mesh = text_to_3d(prompt)\nexcept FalError:\n    mesh = text_to_3d(prompt)  # risks duplicate paid job\n\n# after\ntry:\n    mesh = text_to_3d(prompt)\nexcept FalError as e:\n    if not provider_job_exists(job_id):  # reconcile before resubmitting\n        mesh = text_to_3d(prompt)\n    else:\n        mesh = fetch_provider_result(job_id)","handlingStrategy":"retry","validationCode":"# validate inputs before submit\nassert endpoint and endpoint.startswith(\"fal-ai/\"), f\"bad endpoint: {endpoint!r}\"\nassert isinstance(payload, dict) and payload, \"payload must be a non-empty dict\"","typeGuard":null,"tryCatchPattern":"try:\n    result = submit(endpoint, payload)\nexcept FalError:\n    # acceptance unknown: check provider job status before resubmitting\n    if job_was_accepted(job_id):\n        result = await_provider_result(job_id)\n    else:\n        result = submit(endpoint, payload)  # safe resubmit","preventionTips":["Never blanket-retry submit(): job acceptance may be unknown, risking duplicate paid generations","Track submitted job ids so you can reconcile status on the provider side after a failure","Validate endpoint names and payloads against the current fal.ai schema (API versions change)","Add a short timeout/budget and log request ids (never exception strings, which may contain keys)"],"tags":["python","network","api","retry-safety"],"backgroundTag":"api-request-failed","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"}