Format run mcp_unavailable: failed before the model, charged false

mcp_unavailable means the per-turn tools never attached, so the run stopped before any turn. details.charged is false. Retry with a new Idempotency-Key.

3 min readSume
All posts

Not charged, safe to retry

If a Format run fails with mcp_unavailable, the per-turn Sume tools the run needed did not attach. The host failed the run before the model started, rather than run a turn without tools. The error details say retryable: true and charged: false. No generation ran and nothing was billed.

The fix is to retry with a new Idempotency-Key. If the error comes back, the docs say the cause is the tools, not your request. In that case send Sume the request_id from the receipt.

What the failure does and does not tell you

The code is easy to confuse with a tool-permission problem on hosted MCP. It is a different thing. This is an internal tool attachment for a Format run, not the OAuth scope check that returns insufficient_scope on mcp.sume.com.

Format run failure codes that are safe to retry, as of 2026-10-08
error.codedetails.retryableCharged?What the docs say to do
mcp_unavailabletrueNo (details.charged is false)Retry with a new Idempotency-Key
provider_unavailabletrueFinished clips stay on the threadRetry with a new key; the retry does not regenerate finished clips
provider_credits_exhaustedfalseCause is on the Sume sideDo not re-fire immediately; wait for Sume to report the provider restored
unattended_blockedn/aDepends on what ranFix the input or brief, then retry with a new key

A retry loop that does not spin

Treat the retry as bounded. One retry is cheap, because a failure before the model starts costs nothing. A loop that retries every few seconds is not. Wait, retry once, and alert if the same code returns.

The create call itself is separate. A 202 never turns into a create-time error later. After you hold a receipt, failures arrive on it as status: "failed", which is where this code appears. On a webhook the run arrives as status: "ERROR" and outcome: "error", with error.code copied from payload.error.code.

  • New key per retry, derived from your item id plus an attempt counter.
  • Keep the failed receipt. It is the evidence if the error repeats.
  • In a bulk queue the item shows only format_run_failed; read the child receipt for mcp_unavailable.

Where to read the code

Poll GET /v1/format-runs/{run_id} or use the terminal webhook. The failed receipt includes error, usually output_error, and artifacts[] (empty here, because nothing ran). Branch on error.code, and keep a fallback for codes you do not know, because the set is open.

Cost and bookkeeping

Because details.charged is false, this failure should not move your wallet. You can confirm it instead of trusting it. usage on the receipt reports billable_amount_usd_micros for the run, and GET /v1/usage?run_id= uses the same ledger rows. A run that failed before the model started should show a billable amount of zero. If it does not, that is worth sending to support with the request_id.

Remember what usage leaves out. billable_amount_usd_micros is generation spend only and does not include the agent's LLM turn. The real wallet deduction is debited_usd_micros. For this code both should be unremarkable, since no turn and no generation ran.

Your own record should keep one row per attempt: the key you sent, the run id, the final error.code, and the time. When a second attempt succeeds, keep the first attempt's row. It is the history that shows the tools failed to attach once, which is the information Sume needs if the pattern repeats.

Sources

Related posts

More in Formats

All Formats posts

Written by Sume