Timeline 1.0 warnings after stitching shots: which need a fix
Timeline 1.0 returns soft warnings, not failures. A list of the codes you will see on a stitched AI film, what each means, and which ones are worth acting on.

A Timeline 1.0 render that finishes with warnings[] has still succeeded. The docs call padded or looped short sources, snapped transitions and ignored still motion soft warnings, not failures, and the MCP tool description lists a fuller set of codes as soft degradations. So the answer to "do I re-render?" is usually no, with a few exceptions you can spot by reading the codes.
This is a reference for the codes you meet when you stitch AI-generated shots together. Where the docs explain a code, I say what it means. Where they only list the name, I say that too rather than guess.
Where do the warnings appear?
A finished render's GET /v1/jobs/:id/result has kind: timeline_render with video_url, duration_seconds, segment_count, billable_minutes and an optional warnings[]. Over MCP, timeline_get reads the same result. The unbilled plan call (POST /v1/timeline-1.0/plan) cannot predict warnings about short sources, so the list below is for after the render, plus a few you can avoid up front.
Which codes are explained in the docs?
The two that most often deserve action on a stitched film are the fps resample and the short-source pad or loop, because both are visible. The rest are bookkeeping.
| Code | What it means | Re-render? |
|---|---|---|
| segment_source_short_padded | A clip is shorter than its slot and was padded | Only if the pad is visible and unwanted: lengthen the clip or shorten the slot |
| segment_source_short_looped | A short clip was looped to fill the slot | Same: a loop on a character shot is usually noticeable |
| transition_downgraded_to_cut | A short source could not carry the fade, so that boundary is a hard cut | No; the job still succeeds |
| transition_snapped_to_frame | A transition duration was moved to a frame boundary | No |
| motion_ignored | A motion field on a still is accepted and ignored | No; stills are static holds |
| still_source_in_ignored | source_in on a still has no effect | No |
| output_fps_resamples_sources | Output fps differs from a source; frames are repeated or dropped | Yes if motion judders: set output.fps to the sources' rate |
| timeline_render_chunked | The render was split into chunks (auto strategy past 12 segments) | No; the result is one MP4 |
| audio_spine_low_fidelity | The spine is low-rate or mono; master keeps that fidelity | Yes if quality matters: use audio_detach output or a TTS master |
Which codes do the docs only name?
The MCP tool description lists these as soft degradations: timeline_gap_filled, video_coverage_shorter_than_audio, output_av_drift, soundtrack_shorter_than_spine, soundtrack_source_replaced, soundtrack_source_omitted and edge_fade_shortened. Their exact triggers are not spelled out in the public docs I read, so treat the names as hints.
What the docs do say can narrow it down. video[].duration coverage may trail the spine by at most 0.5 seconds, which is the territory of video_coverage_shorter_than_audio and timeline_gap_filled. The soundtrack bed has its own loop, fade_out_seconds and duck_db settings, which is where the soundtrack_* codes come from. Edge fades must not exceed the output length (edge_fades_exceed_output is the hard refusal), so edge_fade_shortened is the softer sibling. If one of these appears and the film plays correctly, the docs give no reason to re-render.
How do I read them in code?
The check below prints the warning codes and flags the three worth a second look. It reads the finished job result, so run it after jobs_wait or after polling the status route. It needs no extra credentials beyond the key you used to submit.
If you want to pre-empt the two visible ones, set output.fps explicitly to the rate your clips share (24, 25, 30 or 60) and confirm each clip's length with a probe before you declare slot durations.
import os, sys, requests
job_id = sys.argv[1]
H = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}
r = requests.get(f"https://api.sume.com/v1/jobs/{job_id}/result", headers=H)
r.raise_for_status()
res = r.json()
res = res.get("data", res)
watch = {"output_fps_resamples_sources", "segment_source_short_looped",
"segment_source_short_padded", "audio_spine_low_fidelity"}
for w in res.get("warnings", []):
code = w.get("code", w) if isinstance(w, dict) else w
print(("CHECK " if code in watch else "ok ") + str(code))
print(res.get("video_url"))What is a failure, not a warning?
Refusals come at submit time with stable codes, and they stop the job before it renders: timeline_must_start_at_zero, segment_overlap, transition_too_long, too_many_chained_transitions (more than 8 adjacent fades; insert a hard cut), render_strategy_unsafe (single above 12 slots) and unsupported_media_source for any off-host URL. These are 400s, not warnings, so they never produce a finished video.
So the practical rule is simple. A 200 or finished job with warnings is a film you can ship; check the visible ones. A 400 with a code is a document you must fix. The unbilled plan route is the cheapest place to find the second kind.
Sources
Related posts
More in Developers
- TTS boundary_lead_ms: why sentence slices end 70 ms after a word
Sume TTS sentence segments cut boundary_lead_ms after a sentence's last word: 70 ms by default, 0 to 500. The next segment absorbs the pause, and no gap opens.
- tts_duration_exceeded: split long scripts for Sume TTS
Sume TTS fails with tts_duration_exceeded when audio would pass 1,200 seconds, and takes at most 20,000 characters. Split rules and how to join the parts.
- TTS language omitted: Spanish text comes out with an English default
On Sume TTS, an omitted language defaults to English at the provider, with a ko or ja fallback only for Hangul or kana text. Set language for all others.
- TTS sentence slices have no audio_url: emit_audio needs wav or raw
With segmentation on, Sume TTS only returns a sample-exact audio_url per sentence for wav or raw output. For mp3 you get timings and a warning instead.
Written by Sume