affaan-m/ECC · error · FalError

fal call failed after one attempt; job acceptance may be…

Error message

fal call failed after one attempt; job acceptance may be unknown. Reconcile provider job status before requesting another generation.

What it means

FalError raised by submit() when the fal client call throws. It intentionally suppresses the original exception (`from None`) because exception strings can contain API keys, signed URLs, and provider payloads. It warns that job acceptance is unknown: the request may or may not have reached fal.ai, so blindly retrying could create duplicate paid generations.

Solutions

  1. Check fal.ai dashboard/job status for the endpoint to reconcile whether the job was accepted before retrying
  2. Retry the call once only after confirming no job was created (avoids double spend)
  3. Verify FAL_KEY is valid and not expired if failures repeat
  4. Add network/timeout logging outside falapi (the library intentionally omits details) to diagnose causes

Example fix

// before
url = falapi.submit(ENDPOINTS["text_to_image"], payload)  # opaque FalError
// after
try:
    url = falapi.submit(ENDPOINTS["text_to_image"], payload)
except falapi.FalError:
    status = reconcile_provider_job(endpoint, job_id)  # check acceptance first
    if status is None:
        url = falapi.submit(endpoint, payload)  # safe to retry now
Defensive patterns

Strategy: retry

Try / catch

try:
    result = falapi.submit(endpoint, payload)
except falapi.FalError:
    # Job acceptance unknown: reconcile provider state BEFORE retrying to avoid double spend
    if not provider_job_exists(endpoint):
        result = falapi.submit(endpoint, payload)
    else:
        result = fetch_existing_job_result(endpoint)

Prevention

When it happens

Trigger: submit() wraps `_fal().submit/ run(endpoint, arguments=payload, ...)`; any exception there — network failure, timeout, HTTP error, auth rejection — triggers this error.

Common situations: Transient network drop mid-request; provider 5xx; expired/invalid FAL_KEY rejected server-side; timeout exceeded on a slow 3D generation endpoint.

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


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

Appendix: source

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

    """Submit once. Ambiguous failures must be reconciled before another job.

    ``max_attempts`` is retained for call compatibility but never resubmits.
    """
    if is_dry_run():
        log.info("[dry-run] model request (payload omitted)")
        return _stub(endpoint, payload)

    require_live()
    api_key()
    try:
        result = _fal().subscribe(
            endpoint, arguments=payload, with_logs=False, client_timeout=timeout,
        )
        return result if isinstance(result, dict) else {"output": result}
    except Exception:
        # Exception strings can include keys, signed URLs and provider payloads.
        # Do not print or chain them into caller tracebacks.
        raise FalError(
            "fal call failed after one attempt; job acceptance may be unknown. "
            "Reconcile provider job status before requesting another generation."
        ) from None


# ---------------------------------------------------------------------------
# uploads (cached)
# ---------------------------------------------------------------------------

_UPLOAD_CACHE: dict[tuple[str, int, int], str] = {}
_UPLOAD_LOCK = threading.Lock()


def _cache_key(path: Path) -> tuple[str, int, int]:
    st = path.stat()
    return (str(path.resolve()), st.st_mtime_ns, st.st_size)

View on GitHub (pinned to 8321021c54)