A partial render (rangeStart > 0) on /render-onserver-job never renders a single frame. The job sits at phaseLabel "frame0: seeking" and then dies with a "Render stalled" error. The SAME project renders fine when rangeStart is 0, so the timeline, codec support and encoder config are all demonstrably OK.
Project: single channel, single video item, 3840×1814 @ 23.976fps, mp4. Source clip is a 392s 4K H.264 file. A full-length render of this exact project completed successfully (544s, browser-webcodecs, system-chrome 151.0.7922.138, GPU on).
Reading videoExporter-*.js: the frame loop gives each frame a 15s budget and throws after 3 consecutive misses, and the time in the message is frameTime + rangeStart. So "stalled near 1.08s" with rangeStart=1 means frames 0, 1 and 2 all timed out – the initial seek never completes and no frame is ever produced.
WHAT I VERIFIED (each line is a separate render job, all at 3840×1814 @ 23.976, same project shape):
– rangeStart 0, rangeEnd 9 -> OK, 216 frames, ~45s
– rangeStart 1, rangeEnd 10 -> FAIL at 1.08s (reproduced 3x)
– rangeStart 1.25125 (exactly on a keyframe), rangeEnd 10 -> FAIL at 1.33s
– same source file, timeline item trimmed to 15s -> FAIL (so timeline length is not the factor)
– a lower-bitrate 19.9 Mbps / 953 MB re-encode of the same footage -> FAIL (so not bitrate or file size)
ELIMINATED as the cause: decode capability (full render works, and /render-still returns the CORRECT composited frame at t=1.0 – I verified it pixel-wise against an ffmpeg-extracted reference frame, so the frame is reachable); keyframe alignment; source duration (a 392s file DOES render at rangeStart=1); declared H.264 level (two 20s files encoded identically except level 4.0 vs 5.1 both FAIL); file size; bitrate; timeline length; media file location.
Container layout is implicated but is not the whole story: for one matched pair with byte-identical mdat (999,751,767 bytes, same duration, same bitrate), the copy with moov at the END fails and the faststart copy passes. But other faststart files still fail, so faststart alone does not explain it.
IMPORTANT: the renderer's own "Checking source clips" / "Optimizing …" pre-pass does not fix this. It produced a bitrate-capped faststart copy in render-cache/ (~20.3 Mbps, 960 MB, same duration/resolution), spent ~6 minutes doing it, and the render still failed identically. Pointing a project directly at that optimized file also fails. So the optimize pass is paying a large cost without changing the outcome.
Net effect: partial renders are unusable on this project. That is the exact case the feature exists for – iterating on one segment of a long timeline without paying for a full-length encode.
I was not able to isolate a single source-file property that predicts pass vs fail. The reproduction is deterministic though: with rangeStart 0 it always works, with rangeStart 1 it always fails, on the same project and same file.
Steps to reproduce
1. Create a video project with one video channel containing one 4K H.264 clip (392s source, 3840×1814, 23.976fps).
2. POST /api/moodboards/{board_id}/video-projects/{project_id}/render-onserver-job with {"format":"mp4","fps":23.976,"rangeStart":1,"rangeEnd":10}.
3. Poll GET /api/video-render-jobs/{job_id}. It reaches progress 8, phaseLabel "frame0: seeking", stays there, then fails after ~90s.
4. Repeat the identical call with rangeStart 0 and rangeEnd 9 – it completes in ~45s.
Expected
A partial render with rangeStart 1 / rangeEnd 10 produces the same 9 seconds that the corresponding span of a full render produces.
Actual
The job never renders a single frame. It sits at phaseLabel 'frame0: seeking' and fails after ~90s with 'Render stalled near 1.08s'. The error suggests re-encoding the clip, but the clip decodes fine – the full render and the rangeStart 0 render both succeed with it.
Error output
: Error: Render stalled near 1.08s - 3 consecutive frames failed to render in the headless browser (a clip likely can't be decoded). Try re-encoding that clip or rendering in a different format.
at Tn (videoExporter-BWYFlTDP.js:8:12680)
at async Object.exportVideo (VideoEditor-BSgm7crZ.js:5149:125940)
at async Object.renderVideo (VideoProjectRenderPage-BSWYdlVx.js:2:5798)
Context
Video Editor / partial (time-range) render. Endpoints: /render-onserver-job, /render-onserver, /render-still. Assets: videoExporter-BWYFlTDP.js, VideoEditor-BSgm7crZ.js, VideoProjectRenderPage-BSWYdlVx.js. Renderer: browser-webcodecs, system-chrome 151.0.7922.138, GPU enabled. Project 3840×1814 @ 23.976fps, single channel, single mp4 video item. Also affects the render-cache 'Optimizing' pre-pass, which completes but does not change the outcome.
Environment
App version: 10.0.0
Platform: Windows 11 (AMD64)