Summary
Rendering a composition that uses the drawElement / html-in-canvas capture path (screenshot-fallback frames) fails deterministically with ctx.drawElementImage is not a function during the capture_streaming phase. The regression was introduced between 0.7.37 and 0.7.38 and is still present on the current latest (0.7.42 as of 2026-07-08). 0.7.37 renders the same composition cleanly. Compositions that do not exercise this capture path render fine on the broken versions.
Repro
A minimal HF project (hyperframes.json + index.html) with a sub-composition block that triggers the drawElement capture path (in our case: an overlay card block combining an <img> avatar, text, and animated elements, rendered to transparent MOV):
npx hyperframes@0.7.42 render <project-dir> -c blocks/follow-card.html --format mov -o out.mov \
--variables '{"avatarPath":"assets/avatar.jpg","displayName":"Example","handle":"@example","counterText":"","showVerified":false}'
Same failure with --format webm. Same failure via bare npx hyperframes render ... (resolves latest).
Observed
Render reaches capture_streaming, injects the drawElement canvas, then fails at 25%:
[initSession:drawelement] drawElement canvas injected (3467ms)
[initSession:drawelement] screenshot fallback: 5 clip-boundary frame(s) (3468ms)
[INFO] [Render:trace] {"phase":"capture_streaming","status":"error","message":"ctx.drawElementImage is not a function"}
██████░░░░░░░░░░░░░░░░░░░ 25% Failed: ctx.drawElementImage is not a function
Failure summary reports observedFailedPhase: "capture_streaming", isTimeout: false, 0 browser console errors. Exit code 1, no output file.
Environment: macOS (darwin arm64, Apple M3 Pro), Node v26.4.0, HeadlessChrome/140.0.7339.207, gl=angle/Metal, browserGpuMode auto → hardware.
Expected
The composition renders to a valid MOV/WebM, as it does on 0.7.37.
Bisection
0.7.37 — renders clean (last good)
0.7.38 — fails (first broken)
0.7.39 — fails
0.7.41 — fails
0.7.42 (current latest) — fails, re-confirmed 2026-07-08
The break is isolated to the drawElement/html-in-canvas capture path: the normal (non-drawElement) render path renders the same project cleanly on all of the versions above. Looks like the drawElement canvas shim injects a canvas whose 2D context no longer carries the drawElementImage extension the streaming capture expects.
Workaround
Pinning the affected renders to npx hyperframes@0.7.37 while tracking latest everywhere else.
Summary
Rendering a composition that uses the drawElement / html-in-canvas capture path (screenshot-fallback frames) fails deterministically with
ctx.drawElementImage is not a functionduring thecapture_streamingphase. The regression was introduced between0.7.37and0.7.38and is still present on the currentlatest(0.7.42as of 2026-07-08).0.7.37renders the same composition cleanly. Compositions that do not exercise this capture path render fine on the broken versions.Repro
A minimal HF project (
hyperframes.json+index.html) with a sub-composition block that triggers the drawElement capture path (in our case: an overlay card block combining an<img>avatar, text, and animated elements, rendered to transparent MOV):Same failure with
--format webm. Same failure via barenpx hyperframes render ...(resolves latest).Observed
Render reaches
capture_streaming, injects the drawElement canvas, then fails at 25%:Failure summary reports
observedFailedPhase: "capture_streaming",isTimeout: false, 0 browser console errors. Exit code 1, no output file.Environment: macOS (darwin arm64, Apple M3 Pro), Node v26.4.0, HeadlessChrome/140.0.7339.207,
gl=angle/Metal,browserGpuMode auto → hardware.Expected
The composition renders to a valid MOV/WebM, as it does on
0.7.37.Bisection
0.7.37— renders clean (last good)0.7.38— fails (first broken)0.7.39— fails0.7.41— fails0.7.42(current latest) — fails, re-confirmed 2026-07-08The break is isolated to the drawElement/html-in-canvas capture path: the normal (non-drawElement) render path renders the same project cleanly on all of the versions above. Looks like the drawElement canvas shim injects a canvas whose 2D context no longer carries the
drawElementImageextension the streaming capture expects.Workaround
Pinning the affected renders to
npx hyperframes@0.7.37while tracking latest everywhere else.