Failed Format run codes: retry, continue, fix input or wait
Eleven error.code values a failed Sume Format run can carry, grouped by response: continue with previous_run_id, retry with a new key, fix input, or wait.

A failed Sume Format run falls into four buckets, and the error.code tells you which. Some failures should continue the same run with previous_run_id, because the finished clips are on the thread and a fresh run would not regenerate them. Some should retry with a new Idempotency-Key. Some need a change to your input or schema. One, provider_credits_exhausted, should not be retried right away at all. Treating all eleven the same way either wastes spend or gives up on work that was nearly done.
The four buckets
The Formats error page lists the codes on a failed run. Read them with two facts in mind. First, the receipt still lists every artifact the run generated, and output carries whatever partial result satisfied your schema, so a failed run is often a partial delivery rather than nothing. primary_output_url is null on every failure, which makes if (run.primary_output_url) a safe test for whether the deliverable exists. Second, the old key is bound to the receipt you already have, so any retry needs a new key.
| error.code | What happened | Response |
|---|---|---|
| incomplete_assembly | Time limit hit with generations unfinished | Continue with previous_run_id |
| primary_output_missing | Schema met, primary key empty | Continue, or retry |
| agent_reported_failure | Run said it did not deliver | Read details.reason, continue or re-fire |
| unattended_blocked | Needed a person: no avatar match or missing input | Fix input or brief, new key |
| output_schema_unsatisfied | Result did not fit your schema | Loosen to nullable or change the instruction |
| deliverable_missing | Media Format produced none | Retry once, new key |
| mcp_unavailable | Tools did not attach; nothing charged | Retry, new key |
| provider_unavailable | Provider stream cut; retryable | Retry, new key |
| output_extraction_failed | Projection could not run | Read again, then retry |
| provider_credits_exhausted | Sume's provider account, not your balance | Wait, do not retry now |
| format_run_failed | Generic, including spend cap | Compare billable with the cap |
A router you can run
The map below turns the code into one of a handful of actions and caps the number of automatic retries, so a flapping provider ends in a page instead of an infinite loop. Unknown codes fall through to a human, because the docs say to treat the set as open. It runs as-is.
ROUTES = {
"unattended_blocked": "fix_input",
"output_schema_unsatisfied": "fix_schema_or_instruction",
"deliverable_missing": "retry_new_key_once",
"primary_output_missing": "continue",
"agent_reported_failure": "continue",
"incomplete_assembly": "continue",
"output_extraction_failed": "read_again_then_retry_new_key",
"mcp_unavailable": "retry_new_key",
"provider_unavailable": "retry_new_key",
"provider_credits_exhausted": "wait_do_not_retry_now",
"format_run_failed": "check_spend_cap",
}
def route(error_code: str, attempts: int, max_attempts: int = 2) -> str:
action = ROUTES.get(error_code, "page_a_human") # the set is open
if action.startswith("retry") and attempts >= max_attempts:
return "page_a_human"
return action
for code, n in [("incomplete_assembly", 1), ("provider_unavailable", 1),
("provider_unavailable", 2), ("brand_new_code", 0)]:
print(code, n, "->", route(code, n))Money and partial work
Failure does not erase what was generated. Generation that finished before a failure or a cancel is still billed, which is another reason to prefer continuing a run over starting one: the finished clips are reused. For the cost of a failed attempt, read /v1/usage?run_id= and use the summary rather than summing rows. A mcp_unavailable failure is the exception worth knowing: its details say nothing was charged because no generation ran.
Over a webhook
The same classification arrives on the webhook. A failed run is delivered as status: ERROR with outcome: error and error.code mirroring the receipt, and a run that completed but could not fill your schema arrives as status: OK with outcome: degraded. Route both through the same table, and run the router in the worker that handles the stored event rather than inside the HTTP handler.
Alerting on codes
Count failures by code per day. A spike in provider_unavailable or mcp_unavailable points at Sume or its dependencies, and the right response is patience and backoff. A spike in output_schema_unsatisfied or unattended_blocked points at your Formats or inputs, and the right response is an edit. A single provider_credits_exhausted is Sume's provider account running out of credit, which is not yours to fix. Different owners, different channels: wire each group to the right one instead of one noisy alert.
Sources
Related posts
More in Formats
- Season output schema: episode videos and final cut as SumeMediaFile
Bind an output_schema with SumeMediaFile fields so a Sume run returns typed episode videos. The URL gate, 10% duration check and parts-versus-cut rule.
- Series bible for a Format: SKILL.md index, references and run input
Where to keep a series bible in a Sume Format: a short SKILL.md index, detail in references/*, and only the per-episode beat in the run input.
- Slideshow Format: a holiday gift guide from up to 30 product images
Send up to 30 product images to Sume's slideshow Format for a gift-guide clip, then check Pinterest's video ad specs before you promote it.
- Bulk Format runs: 100 items, 16 at once, what completed means
Sume bulk runs take 1 to 100 items at concurrency 1 to 16. A queue marked completed means every item is terminal, not that every item succeeded.
Written by Sume