fix(render): reject incomplete captured frames#2293
Conversation
james-russo-rames-d-jusso
left a comment
There was a problem hiding this comment.
Reviewed at 3bda0b9c.
Correct root-cause fix. Verified findMissingFrameRanges is the single canonical "which frames need retry" gate — callers at renderOrchestrator.ts:844,881,943 all pipe through this one function. No sibling existsSync-only checks elsewhere in the producer that would still accept placeholder frames.
The 8-byte threshold correctly catches the reported failure mode: PNG's full magic signature is exactly 8 bytes, and any legitimate JPEG is far larger than its 3-byte SOI marker. <= 8 cleanly separates "worker exited between open() and write()" from "real captured frame." Short-circuit !existsSync(framePath) || statSync(...) avoids the ENOENT case on the fast path.
Test coverage matches the fix's shape: the new test proves a 1-byte placeholder mid-sequence gets reported as a retry range, and the earlier tests were rewritten from "x" (1 byte) to "captured-frame" (14 bytes) so the existing "contiguous missing" test still exercises the presence path rather than accidentally tripping the new guard. Ratchet.
Not addressed here (and probably not this PR's job): JPEG/PNG files that survive the size threshold but are still structurally truncated (e.g., a worker that crashed after writing headers but before end-of-image markers). If that recurs on Windows post-fix, a follow-up could tighten to a decoder-level integrity check — but decoding N frames on the retry path would be a real perf hit for the tail case. The 8-byte pragmatic minimum is the right first cut.
LGTM.
jrusso1020
left a comment
There was a problem hiding this comment.
Approving on Rames-D's go (R2 delta clean, nit round addressed) + Magi's CI-green confirmation. Verified at final head 3bda0b9c: CI green, no changes-requested, mergeable.
What
Treat tiny capture-worker frame placeholders as missing frames before encoding.
Why
A Windows multi-worker render reported success even though its video stopped at frame 2,855 while audio continued to the full 229.5 seconds. Locally, an image sequence containing a one-byte worker placeholder reproduced the integrity failure: FFmpeg stopped at the placeholder, emitted only the prefix, and still exited with status 0. The existing capture continuity check only tested file existence, so it accepted the placeholder as a completed frame.
How
Test plan
bunx vitest run src/services/renderOrchestrator.test.ts(140 passed)bun run test:unitbun run typecheckbunx oxfmt --check src/services/renderOrchestrator.ts src/services/renderOrchestrator.test.tsbunx oxlint src/services/renderOrchestrator.ts src/services/renderOrchestrator.test.ts