Sume Format run status is spelled canceled with one L: fix your switch
A Format run ends as completed, failed, canceled or skipped. If your code matches cancelled with two Ls, a canceled run will look like it never ended.

Sume writes the cancel status with one L: canceled. If your poller checks for cancelled, a canceled run never matches your terminal list, and the loop keeps polling until its own timeout. The status values on a Format run are queued, processing, completed, failed, canceled and skipped, per Sume's Runs and results page (read 2026-10-04).
It is a one-character bug and it hides well, because the run is fine and only your code misses it.
Which statuses are terminal?
The poll is over when a run reaches one of four.
| Status | Terminal? |
|---|---|
queued | No |
processing | No |
completed | Yes |
failed | Yes |
canceled | Yes |
skipped | Yes |
How do I write the check safely?
Use one shared constant, and treat the next_action field as a second opinion.
TERMINAL = {"completed", "failed", "canceled", "skipped"}
def is_done(run: dict) -> bool:
return run["status"] in TERMINAL or run.get("next_action") == "none"
Why check `next_action` as well?
Because it is the server's own verdict: poll_status means keep going, retry_later is a transient gap, and none means stop. If a status spelling ever surprises you, next_action still ends the loop.
Sources
Related posts
More in Developers
- Sume Free plan and Omni: one running, five queued, seventh gets 429
On a Sume Free workspace one video job runs and five wait; a seventh submit returns 429 queue_full. What that means for an Omni test batch and its cost.
- Sume image 400s name the valid values: retry in code
Sume's Image API 400 bodies carry details.supported, allowed, min and max. A tested error table and a small function that retries with a valid value.
- Sort Sume image models by created? The field is one shared value
GET /v1/images/models returns the same created timestamp for every model, so it cannot tell you which is newest. What to use instead, with a script to prove it.
- Split a Sume job's queue wait from its run time with job events
Read GET /v1/jobs/{id}/events and subtract timestamps: job.queued to job.started is queue wait, job.started to the terminal event is run time. Python sample.
Written by Sume