Sume 409 job_not_queued: the job left the queue before it started
What the Sume 409 job_not_queued means: a submit found its job no longer queued, sent nothing to the provider, and the error is not retryable by resending.

job_not_queued is a Sume 409 with the message The job left the queue before generation started. It means the API was about to hand a paid job to the generation runtime, found that the row was no longer queued (it had been canceled in the meantime), and stopped before sending anything. Do not loop on it: read the job, and submit a new request only if you still want the clip.
When does the API raise it?
Before a submit reaches the provider, the API writes a write-ahead mark on the job: from that point the job is no longer cancelable, because a request may be on its way to a billable provider. That mark only succeeds while the row is still queued. If a cancel landed between creation and the mark, the mark fails and the API raises job_not_queued instead of submitting.
The order matters for money. The API code explains that a cancel after an accepted submit used to refund a request the provider still bills, so the mark now comes first. The cancel settles the row, so this error path does not mark it failed or refund it a second time.
How does the envelope classify it?
job_not_queued has no special branch in the public error classifier, so a 409 with this code falls to the generic 4xx answer: category: validation, retryable: false, public_reason: job_not_queued, next_action: fix_input. The error is raised without details, so the body does not carry the job id. That differs from the 400 and 502 submit failures, which do.
| Code | Meaning | Next step |
|---|---|---|
job_not_queued | Submit found the job already left queued | Read the job; resubmit only if you want it |
job_generation_already_started | Cancel arrived after generation began (details.cancelable: false) | Let the job finish or fail |
job_not_completed | Result requested before the job is terminal | Poll status, then fetch |
What should my client do?
Treat it as a signal that your own state is stale. Only the member who created a job can cancel it, so the cause is a cancel from your key or your session, or an operator stop. Call GET /v1/jobs or GET /v1/jobs/{id}/status and read status: canceled means you are done, and failed with an ops_ code is a documented operator stop whose hold was refunded, which makes a resubmit the right move.
If you retry the submit, keep one Idempotency-Key per intended clip and let the dedupe do its work. Do not wrap the submit in a loop that cancels and resubmits on a timer; that pattern is the usual way to meet this error.
Sources
Related posts
More in Developers
- Sume generation_capacity_exhausted: the 503, job reason and flag
Sume reports provider capacity three ways: HTTP 503 provider_capacity_exceeded, a job reason generation_capacity_exhausted, and a sync flag. All three retry.
- Sume job failed artifact_too_large: shrink the output, don't rerun
A Sume job failing with artifact_too_large or artifact_upload_rejected made its file but could not store it. Make the file smaller; rerunning changes nothing.
- pending_usd_micros vs held: what Sume's settle sweeper still owns
Sume /v1/usage splits open holds into held and pending_usd_micros. Read the two fields and settle_state to tell parked rows from spend, and when final flips.
- unpriced_usd_micros: legacy rows still inside Sume's debited total
unpriced_usd_micros in Sume /v1/usage is captured spend from legacy rows with no price-book stamp. It is inside debited, so never subtract or add it twice.
Written by Sume