A failed Sume video poll has error as a string, not an error object

On /v1/videos, HTTP errors use {error:{code,message}} but a failed poll carries error as a string. Read both without a TypeError in Python and TypeScript.

3 min readSume
All posts

A 200 poll with status failed carries error as a plain string, while a real HTTP error such as 402 or 429 carries an envelope {error:{code,message,request_id,details}}. Code that reads poll.error.message on a failed job gets undefined in TypeScript or a TypeError in Python.

Two places an error can live

The poll body is a bare object with id, generation_id, polling_url, status, model, unsigned_urls, usage and error. When the job failed, error is the text. When the poll request itself fails, you get a non-2xx status and the envelope.

Handle both, and log the x-sume-request-id response header on the second case; the string case has no code to branch on.

Where the error is, and the shape (read 2026-10-09)
SituationHTTP statusWhereShape
Job failed200poll body, errorstring
Not enough balance402response body, errorobject with code and message
Too many requests429response body, errorobject, error.details.scope
Content before completion409response body, errorobject, job_not_completed or job_failed

A reader that handles both

The function returns one string for logs and never raises on shape.

def error_text(status_code, body):
    err = body.get("error")
    if isinstance(err, str):
        return err  # failed poll: plain text
    if isinstance(err, dict):
        code = err.get("code", "error")
        return f"{status_code} {code}: {err.get('message', '')}"
    return f"{status_code} unknown error"

# poll = requests.get(polling_url, headers=h)
# if poll.json()["status"] == "failed":
#     print(error_text(poll.status_code, poll.json()))

Gotchas

A failed job is not a reason to resubmit blindly: check the text first. A bad input URL is fixed by changing the input, and each resubmit of a 30 s Wan 3.0 clip at 720p reserves $3.75 again, so three blind tries reserve 3 x $3.75 = $11.25.

The docs sample uses status.get('error', 'Unknown error') in Python and status.error ?? 'Unknown error' in TypeScript, which is the same idea in one line.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume