Repository navigation
fix(engine): report a pending setup as a setup timeout, not zero duration - #7211
Conversation
…ration When the runtime never reaches render-ready, __hf.duration reads 0 because the bridge masks it, so pollHfReady's timeout reported "Composition has zero duration" even for compositions with a declared data-duration whose window.__hf.buildReady promise was still pending. Headline that case as "Composition setup did not finish within <timeout>ms", skip the duration inference hint that cannot apply yet, and note that the render clock stays at 0 until the first frame. Keep its transient retry classification and give it its own CLI diagnostic code. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Edit accuracy: accurate 267 (base branch 267), smooth 113 of thoseThe gate passes. Quarantined, measured but not gated (8)
Unstable (1)
|
There was a problem hiding this comment.
Verdict: APPROVE · 0 blocker · 0 important · 0 nits
The headline now comes from renderReady, and every in-repo matcher is updated: captureFailure (still transient) and the CLI captureCodeOf. The only out-of-repo consumers are EF's classifier (#65311 in experiment-framework) and HFI's stderrKind (now other), and the PR body names both. CI is green at e353a6d. One note for #7213: this hint tells authors that waiting on the clock never finishes. That stays true after #7213, which keeps Date and performance.now frozen.
— Genesis
Setup that awaits requestAnimationFrame hits the same render-clock rule as setup that waits on Date or performance.now: frames only fire on a seek, and the first seek waits for setup. Say so, and point at the waits that work. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Chrome runs scheduler.yield() continuations ahead of ordinary tasks, so a setup loop that polls with it starves the setTimeout-driven work it waits on (Three's compileAsync polls with setTimeout(10)) and never finishes. Plain headless Chrome 152 hangs on a ten-line page that does exactly that. Point authors at setTimeout and say why yield-polling does not work. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
HyperFrames guidance is no system timers, so the hint should not tell authors to wait with setTimeout. Point them at the library's own readiness promise (Three.js renderer.compileAsync) and keep the warning about scheduler.yield() polling loops. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
A scheduler.yield() polling loop starves the page, so the readiness poll never returns and the render reports a capture stall instead of this message. Drop that sentence; the hint covers animation-frame and clock waits only. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
There was a problem hiding this comment.
Verdict: APPROVE: 0 resolved, 0 open, 0 new · 5508ff2 → 4da6c5e. Supersedes my 5508ff2 note: scheduler.yield() is not safe advice. The hint now only covers animation-frame and clock waits, and its example holds under the strict clock. Three.js compileAsync (r187) checks shader status on its own setTimeout, with no animation frames and no clock. CI is green.
— Genesis
…eview Adopts or partially adopts 8 groups: capture-failure diagnostics and frame-capture retry in engine, ffprobe fixes, renderOrchestrator updates, studio-server render/files/source-mutation routes, CLI screenshot retry and init/snapshot/timeline fixes, and the motion-blur land-then-undo path (fork seek recovery kept). Left out with ledger reasons: heygen-com#7211 render diagnostic CLI, heygen-com#7089 reverse start; heygen-com#7220 deferred. Core packed budget grows by the measured 1065 bytes since upstream heygen-com#7191 changed no budget. Watermark advances to 659ef56. Co-authored-by: Miguel Ángel <[email protected]> Co-authored-by: WaterrrForever <[email protected]> Co-authored-by: Vance Ingalls <[email protected]> Co-authored-by: James Russo <[email protected]> Co-Authored-By: Claude Opus 5.5 <[email protected]>
What
When a render gives up waiting for the page to finish setup, the error now says so:
Composition setup did not finish within 45000ms.It used to sayComposition has zero duration., even for compositions that declare adata-duration. The CLI reports a new code for it,COMPOSITION_SETUP_TIMEOUT.Why
Before render-ready, the bridge reports
__hf.durationas 0. So whenpollHfReadytimed out because awindow.__hf.buildReadypromise never settled, the timeout headline said the composition had zero duration. That sends authors looking at their timing attributes when the real problem is setup that never finished. We hit this on a Three.js path-tracing study: its setup waited on an animation frame, which the render clock holds until the first seek.Related work
Refs the 3D path-tracing follow-up. EF's render-metrics classifier gets a matching row in heygen-com/experiment-framework#65311. We considered letting animation frames run before the first seek (#7213) and closed it, because it made frame-counting loops depend on load time. The render clock stays strict, and this message tells authors how to wait instead.
How
buildZeroDurationDiagnostictakes the timeout and picks the headline fromrenderReady:buildReadyhint now also explains the render clock.Dateandperformance.nowstay at 0, andrequestAnimationFramecallbacks wait until the first frame, so setup that awaits either never finishes. The hint points authors at the library's own readiness promise (for Three.js,renderer.compileAsync), not a hand-written timer.scheduler.yield()polling loop. In plain headless Chrome 152 (macOS Metal and Linux), a ten-line page that polls asetTimeoutflag withawait scheduler.yield()never finishes loading, because yield continuations outrank timers. That starves the page, so the readiness poll never returns and the render ends in a capture stall instead of this message. That guidance goes in the 3D docs and starter recipe.zero duration ... Runtime ready: falsemessage.COMPOSITION_SETUP_TIMEOUT.Other consumers that match on the old text:
studio-contractsstderrKind: mapsComposition has zero durationtocomposition-empty. Setup timeouts will now land inotherthere, which is more accurate than "empty".Test plan
frameCapture.test.ts: three cases. A pending setup gets the setup headline and the clock hint. The timeline hint is skipped while pending. A ready, zero-duration page keeps the old headline.captureFailure.test.ts: the new message is classified as transient.renderDiagnostic.test.ts: the new message maps toCOMPOSITION_SETUP_TIMEOUT.frameCapturecases fail on main and pass here.performance.now()to advance, or awaits one animation frame,, using the CLI built from this branch (software GL). It fails after 45 s with:🤖 Generated with Claude Code