Four places a Format run fails, and a message for each

Format runs fail at submit, during the run, as a non-failure terminal state, or at webhook delivery. Each needs its own retry rule and its own UI message.

5 min readSume
All posts

A Format run can go wrong in four distinguishable places: at submit, where nothing ran and nothing was charged; during the run, where a run existed and produced no result; at a terminal state that is not a failure; and at webhook delivery, where the run is fine and your endpoint was not. Your UI needs a different message and a different retry rule for each, and collapsing them into 'something went wrong' is the fastest way to a ticket you cannot answer.

The four places

The first split is whether a run exists. A 4xx at submit is a bug in your call, not a transient, so retrying insufficient_scope forever is a common and expensive mistake. A 402 is a funding problem, and nothing ran.

Where a Format run fails (read 2026-10-03)
PlaceSignalsRetry rule
Submit403 insufficient_scope, 404 format_not_found, 409 format_api_trigger_disabled, format_inactive, idempotency_conflict, 400 invalid_request, 402 insufficient_creditsFix the call or the account; nothing was charged
Runstatus failed with error.code such as unattended_blocked or format_run_failed, plus output_errorNew Idempotency-Key; continue with previous_run_id if clips were left behind
Terminal, not failurecanceled or skippedRead the response you already have; no webhook arrives
Deliverywebhook_delivery failed or exhausted, or payload null with payload_too_largeFetch result_url; run is unchanged

Messages worth writing

Some run errors are written to be shown. unattended_blocked means the run hit a gate it could not pass without a person, for example no avatar matched the brief, and its message is meant for display. Others are not about your input at all: provider_unavailable is retryable and nothing about your input caused it, while provider_credits_exhausted is on Sume's side and not retryable right away.

A run that wanted to spend past its cap lands on the generic format_run_failed. Compare usage.billable_amount_usd_micros with usage.generation_spend_cap_usd_micros before you tell a customer to rewrite their brief.

def ui_message(run):
    err = run.get("error") or {}
    code = err.get("code")
    if run["status"] == "canceled":
        return "Stopped by you."
    if run["status"] == "skipped":
        return "Another run was already in progress."
    if code == "unattended_blocked":
        return err.get("message", "We need a different input.")
    if code in ("provider_unavailable", "mcp_unavailable"):
        return "Temporary problem on our side. Try again."
    if code:
        return "This run did not finish. Support code: " + code
    return "Done."

Terminal does not mean failed, and delivered does not mean usable

A canceled run never delivers a webhook, and neither does a skipped one, so a webhook-only integration must read the status off the cancel or create response. A delivery can also be OK with outcome: degraded: real media is in artifacts[] but output is null because the projection did not match your schema. Branch on outcome when the question is whether you got usable output.

One last rule keeps the support queue short: log x-sume-request-id and the receipt's request_id, together with the run id and the error.code. Those are what support asks for, and you should never send API keys, signing secrets or raw media URLs with them.

Sources

Related posts

More in Formats

All Formats posts

Written by Sume