SumeRunTimeoutError: the run keeps billing, resume with its run id
In @sume-com/sdk, SumeRunTimeoutError means your wait ended, not the run. It carries runId and lastStatus: store them and read the receipt later.

SumeRunTimeoutError from @sume-com/sdk means your wait deadline passed, not that the run failed or stopped. The error carries runId and lastStatus: save both, and read the run again later from its result_url or with waitForRun.
The default deadlines are 20 minutes for subscribeFormatRun and 10 minutes for waitForRun, per Waiting for runs and jobs. Video Formats routinely run 10 to 20 minutes, so a 10-minute waitForRun can time out on a healthy run.
Which error class means what?
The helpers throw instead of resolving because a poll loop has nowhere to put a non-result. Terminal statuses, including failed, still resolve, so a failed run is not an exception.
Generation jobs have the same pair under different names: SumeJobTimeoutError and SumeJobRequestError, both carrying jobId.
| Error | When | Run still going? |
|---|---|---|
| SumeRunTimeoutError | Your timeout elapsed first | Yes |
| SumeRunRequestError | Create refused, or a read failed non-transiently | Depends: no run if create failed |
| The signal's reason | You aborted | Yes |
What should the catch block do?
Mark the run pending, not failed. The run is executing and spending, and losing the handle is far more expensive than waiting another minute, which is why the helpers tolerate transient 429 and 5xx reads in the first place.
If you need to stop the spend, cancel through the API; a timeout does not cancel anything.
import { SumeRunTimeoutError, waitForRun } from "@sume-com/sdk";
try {
const run = await waitForRun(runId, { client, family: "format" });
console.log(run.status);
} catch (error) {
if (error instanceof SumeRunTimeoutError) {
// still running: persist and resume later
await markPending(error.runId, error.lastStatus);
} else {
throw error;
}
}How do I avoid timeouts on long runs?
Skip the wait. Pass communication.webhook_url and take the signed format.run.terminal delivery described in Run webhooks, keeping polling as the backup.
Alternatively raise timeout above the run's expected length and add an AbortSignal so a deploy can stop the wait cleanly.
What Sume does not do
There is no SSE stream today, so subscribe means create-then-poll. onStatus reflects status polling, not a live log feed.
Quick checklist
The points above reduce to a short list you can paste into a runbook.
- Catch SumeRunTimeoutError separately from SumeRunRequestError.
- Persist runId and lastStatus before you give up waiting.
- Read the receipt later from result_url or with waitForRun.
- Use a webhook for runs that routinely take 10 to 20 minutes.
- Cancel explicitly if you want the spend to stop.
Sources
Related posts
More in Developers
- verifyWebhook returns false during a Sume secret rotation
The npm build of @sume-com/sdk 0.2.0 compares the signature header for equality, so rotation deliveries with two signatures fail. A 21-line fix.
- Does the Sume SDK retry POSTs? Only with an Idempotency-Key
createSumeClient retries 408, 429 and 5xx twice with backoff, but replays a POST only when it carries an Idempotency-Key. How to set it and tune maxRetries.
- Sume SDK idempotency key: idempotencyKey option or header?
subscribeFormatRun takes an idempotencyKey option and generates one for you; generated operations like generateVideoV1 need the idempotency-key header.
- @sume-com/sdk waitForJob is not exported: a 26-line replacement
The docs show waitForJob, but the npm build of @sume-com/sdk 0.2.0 does not export it. Here is a fetch version with 429 tolerance and a deadline.
Written by Sume