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
- 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.
- Open and close a clip with a white flash: the fade filter
Fade a clip in from white and out to white with two fade filters in Sume video filter. Out time comes from the clip duration; audio is untouched.
- Add a zoomed detail inset to a video: crop, scale, overlay
Show a magnified product detail in the corner of the same clip using one Sume video-filter graph: split, crop, scale 2.4x, white border, overlay. $0.02.
Written by Sume