previous_run_id errors on a Format run: 404, 400 and 409 decoded
Continuing a Sume Format run can fail with previous_run_not_found, format_mismatch, not_terminal or not_resumable. Which are retryable and how to fix each.

Sending previous_run_id on a Sume Format run can be refused four ways: 404 previous_run_not_found, 400 previous_run_format_mismatch, 409 previous_run_not_terminal and 400 previous_run_not_resumable. Only the 409 is worth retrying as is, after the earlier run finishes; the others need a different call.
Continuing is how an integration retries one scene without paying for the whole show again, so these refusals tend to appear in a retry path that was only tested on the happy case. This post gives each code, its cause and the fix.
What does each refusal mean?
The runs page lists the four refusals. They are all caught at create, so nothing runs and nothing is charged. A continuation is a new run with its own id, receipt, spend cap and single webhook, and the original run never changes.
Read code, not the status alone: two of the four share 400, and one shares 404 with the generic missing-run case.
| Status and code | Cause | Fix |
|---|---|---|
| 404 previous_run_not_found | Unknown id, or another owner's run | Check the id and the key you hold |
| 400 previous_run_format_mismatch | The run was created on a different Format | Continue it on the Format where it started |
| 409 previous_run_not_terminal | The run has not finished | Poll it to terminal, then call again |
| 400 previous_run_not_resumable | No thread_id, or neither completed nor any artifacts | Start a fresh run |
How do I know a run is continuable before I call?
Read it off its own receipt. The run must have a non-null thread_id, and it must either be completed or have a non-empty artifacts[]. A failed run that left work behind can be continued, and one that left nothing cannot, which is the previous_run_not_resumable case with details reporting previous_run_status, has_thread and artifact_count.
Checking first saves a write. The sample applies the documented test to a receipt you already hold.
def can_continue(run):
if run.get("thread_id") is None:
return False, "no thread_id"
if run["status"] in ("queued", "processing"):
return False, "not terminal: poll first"
if run["status"] == "completed" or run.get("artifacts"):
return True, "continuable"
return False, "nothing to continue: start a fresh run"
print(can_continue({"thread_id": "thr_1", "status": "failed", "artifacts": [{"type": "video"}]}))
print(can_continue({"thread_id": "thr_1", "status": "failed", "artifacts": []}))
print(can_continue({"thread_id": None, "status": "completed", "artifacts": []}))What else must a continuation get right?
Bind the same output_schema every turn, because it is per run, not inherited. Give the continuation its own Idempotency-Key, since the original key is bound to the original receipt; the retry-one-scene example uses a suffix such as -retry-sc7. Set a spend cap sized for the part you are redoing, not the whole show.
Continue by naming previous_run_id, never by sending a thread id: that is 400 unknown_parameter. See the unknown parameter post for how to read that suggestion.
Which Format does the run belong to?
The format mismatch is the one that surprises people running several Formats from one pipeline: the id is valid and yours, but you sent it to a different {handle}/{slug}. The receipt's format.id and format.slug name where it started, so store them next to the run id when you create it. For the whole retry flow end to end, read retry one scene on the same thread.
Sources
Related posts
More in Formats
- What a Format run receives: instruction order and the input file
A Format run composes the Format pointer, the package, your instruction, an unattended block and an input file at /workspace/inputs. Order and what wins.
- Format run provider_credits_exhausted: not your balance, wait
provider_credits_exhausted means Sume's model provider account ran out of credit, not your balance. Do not retry right away; wait, then use a new key.
- Format run status_url or result_url: which one do I poll?
Poll status_url for a small payload, then read result_url once the run is terminal. result_url answers 409 run_not_completed while the run is in flight.
- Format run stuck in queued: read queue.state and retry_after_seconds
A Sume Format run that stays queued carries a queue block. waiting is normal; runtime_unavailable means nothing claimed it. What to read, and when to ticket.
Written by Sume