waitForJob on a failed Sume image job: read the record, skip /result
waitForJob resolves for failed and canceled jobs instead of throwing, and /result returns 409 job_not_completed for them. How to branch on job.status.

In @sume-com/sdk, waitForJob resolves with the terminal job for any terminal status, not just completed. The SDK source explains why: it reads /v1/jobs/{id} for the final hop, because GET /v1/jobs/{id}/result answers 409 job_not_completed for failed and canceled jobs, and there would be nothing to hand back.
So a failed Ideogram or gpt-image-2.5 job is a result you asked for, not an exception. Branch on job.status, exactly as a webhook handler would.
Branch on the status
import { createSumeClient, waitForJob } from "@sume-com/sdk";
const client = createSumeClient({ apiKey: process.env.SUME_API_KEY! });
export async function finish(jobId: string) {
// Resolves for completed, failed and canceled. It throws only on timeout or a read error.
const job = await waitForJob(jobId, { client, timeout: 5 * 60_000 });
switch (job.status) {
case "completed":
return { ok: true as const, job };
case "failed":
return { ok: false as const, reason: job.error }; // not GET /result: that is a 409
case "canceled":
return { ok: false as const, reason: "canceled" };
default:
throw new Error(`unexpected non-terminal status ${job.status}`);
}
}What does throw
| Situation | What you get |
|---|---|
| completed | Resolved job |
| failed or canceled | Resolved job with status and error |
| timeout before a terminal status | SumeJobTimeoutError with jobId and lastStatus |
| status read fails with an API error | SumeJobRequestError with status and body |
Habits that follow
- Do not call
/resulton a job you have not confirmedcompleted; it is for finished output only. - On a timeout the job is still running and billable. Keep
jobIdand resume instead of resubmitting. - A failed generation is not billed, but log the error object so you can tell a bad prompt from a provider fault.
Sources
Related posts
More in Developers
- waitForJob onStatus also fires on the terminal poll: Sume SDK
In @sume-com/sdk, onStatus runs on every status read, including the last one. Use it for progress and take the result from the job waitForJob returns.
- waitForJob pollInterval is a floor: Sume's hint can only lengthen it
Lowering pollInterval in waitForJob does not poll faster than the server asks. The SDK takes the larger of your interval and next_poll_after_seconds.
- Wan 3.0 lists 20 references; Sume caps 10 images, 5 videos, 5 audio
Wan 3.0's own page says up to 20 reference assets. Sume splits that into 10 images, 5 videos and 5 audio clips. Validate a request offline in Python first.
- What a 30-second Wan 3.0 job reserves on Sume: list times 1.25
Sume reserves the provider list price times 1.25 at submit. Work out the hold for a 30-second Wan 3.0 clip and other models in Python.
Written by Sume