Timeline failed with source_not_found: read source_slot to find it
A failed Sume Timeline job names the dead input by slot, like video[3] or soundtrack, plus host and 404 or 410. Replace it with a media.sume.com asset URL.

When a Sume Timeline render fails because a clip URL answered 404 or 410, the failed job says which one: public_reason is source_not_found (or bgm_source_not_found for the soundtrack), details.source_slot is a slot such as video[3], and the message tells you to replace that slot with a durable media.sume.com asset URL. Retrying the same source fails the same way.
What does the failed job contain?
The public job error for a dead timeline source is category: validation, retryable: false, next_action: fix_input. Its details expose only safe fields: segment_index, source_slot, source_status (404 or 410) and source_host (a bare hostname). The offending URL is never returned, because you sent it and can look it up from the slot.
The slot grammar is closed: video[N], audio, audio.parts[N] or soundtrack. The message for a video or audio slot reads Timeline video[3] was not found. Replace that slot with a durable media.sume.com asset URL — not the original provider URL. Resubmitting the same source will fail the same way.
Why is a dead soundtrack a different reason?
A missing music bed is not a missing clip. When the slot is soundtrack, the reason becomes bgm_source_not_found and the message says to pick another catalog track or omit the soundtrack, and not to remirror video clips that already exist as Sume assets. That stops an agent re-importing nine good clips because one audio file moved.
| Field | Value | Use it to |
|---|---|---|
public_reason | source_not_found or bgm_source_not_found | Branch the fix |
details.source_slot | video[N], audio, audio.parts[N], soundtrack | Find the entry in your request |
details.source_status | 404 or 410 | Tell dead from moved |
details.source_host | Hostname only | Spot an expired CDN |
next_action | fix_input | Stop retrying |
How do I map the slot back to my request?
The Timeline docs also say the API rejects off-host URLs at admission: clips must be Sume-hosted, which you get by importing first. A dead URL therefore usually means an asset URL that was deleted, or a request built from an old provider link. This helper turns the error object into a sentence and the entry to fix.
import re
def explain(error: dict, video: list[dict]) -> str:
details = error.get("details") or {}
slot = details.get("source_slot", "")
if error.get("public_reason") == "bgm_source_not_found" or slot == "soundtrack":
return "Soundtrack is dead: pick another catalog track or drop soundtrack."
match = re.fullmatch(r"video\[(\d+)\]", slot)
if match and int(match.group(1)) < len(video):
entry = video[int(match.group(1))]
return f"Replace video[{match.group(1)}] ({entry.get('source_url', '?')}) with an asset URL."
return f"Replace {slot or 'the named slot'} with a media.sume.com URL."
err = {"public_reason": "source_not_found", "details": {"source_slot": "video[1]", "source_status": 404}}
print(explain(err, [{"source_url": "https://media.sume.com/a.mp4"}, {"source_url": "https://media.sume.com/b.mp4"}]))Sources
Related posts
More in Media tools
- Video frames API returns 202, not 200: poll GET /v1/video-frames/:id
Sume video frames always answers 202 and ignores mode sync. Poll GET /v1/video-frames/:id until resource_status is ready, then read frames[].url.
- Video trim 400 video_trim_range_required: add end or duration
The Sume video trim API returns video_trim_range_required when the body has start but neither end nor duration. Send exactly one of the two; here is the fix.
- Which Sume media routes need a flag, and which are on prod?
Remix media, reference ingest and the trending-videos rebuild are flag-gated; video inspect, frames, trim, detach, filter and timeline are on dest and prod.
- Whistle word timestamps to burned captions with Sume's words field
Turn Whistle's on-device word timings into burned-in captions: map them to words with text, start and end, then call Sume video captions with no STT run.
Written by Sume