Describe the bug
Follow-up to #3340 / #3342. Duplicate media ids across nested compositions with a compile-time src now get a document-unique data-hf-render-id and both clips render.
The residual: <video id="clip" src=""> plus el.src = url in the scene script. Legal per file, check clean. The static parse skips empty src, so those clips exist only in the browser snapshot. That snapshot still keys by author id. After inline, last write wins:
- Scene A (0–4s,
data-media-start="10") gets scene B’s window — footage from ~40s.
- Scene B (4–8s,
data-media-start="40") gets nothing injected — blank panel.
Scene chrome still paints. Preview is correct (each scene’s script is scoped). Export disagrees.
#3342 stamps render ids only when a playable source is already on the element, which is why this path never got one. Native url(#…) / <use> is a different hole (#3490).
Link to reproduction
https://github.com/ArcadeHQ/hyperframes-repros/tree/patch/runtime-src-duplicate-ids
Steps to reproduce
- Clone https://github.com/ArcadeHQ/hyperframes-repros and check out
patch/runtime-src-duplicate-ids.
- Run
npx hyperframes@latest check — 0 errors (duplicate ids across files are allowed).
- Preview: both scenes show the burnt-in seconds counter (~12 in scene A, ~46 in scene B).
- Run
npx hyperframes@latest render . -f 10.
- Open the MP4 at t≈2s and t≈6s.
snapshots/ has actual vs expected frames.
Control: rename scene B’s video id to clip-b (and its script selector). Both windows render correctly.
Expected behavior
Scene A shows the counter around 10–14. Scene B shows it around 44–48. Same as preview.
Actual behavior
On hyperframes@0.8.15 (latest):
- t≈2s: counter reads ~42 (scene B’s
data-media-start).
- t≈6s: white panel, no footage.
Environment
hyperframes doctor
✓ Version 0.8.15 (latest)
✓ Node.js v24.19.0 (darwin arm64)
✓ CPU 10 cores · Apple M1 Pro @ 2400MHz
✓ Memory 16.0 GB total · 3.5 GB available
✓ Disk 358.9 GB free
✓ Frames cache /var/folders/bl/c4hk6r7n34g1d81txd99gsgr0000gn/T/hyperframes-extract-cache-501 · 358.9 GB free at /var/folders/bl/c4hk6r7n34g1d81txd99gsgr0000gn/T/hyperframes-extract-cache-501 · default
✓ Archive extractor unzip
✓ Environment non-TTY
✗ whisper-cpp Not found (optional — needed for transcription)
✗ TTS (Kokoro) Not installed (optional — local voice fallback)
✗ BGM (MusicGen) Not installed (optional — local music fallback)
✓ FFmpeg ffmpeg 8.1.2 at /opt/homebrew/bin/ffmpeg
✓ FFprobe ffprobe 8.1.2 at /opt/homebrew/bin/ffprobe
✓ Chrome cache: /Users/val/.cache/puppeteer/chrome-headless-shell/mac_arm-152.0.7977.42/chrome-headless-shell-mac-arm64/chrome-headless-shell
✗ Docker Not found
✗ Docker running Not running
Additional context
The source is a synthetic ffmpeg testsrc clip with a burnt-in seconds counter, so the wrong window is readable off the frame. Related, not the same: #3340 (static src, fixed by render keys), #3490 (SVG url(#) / <use>).
Describe the bug
Follow-up to #3340 / #3342. Duplicate media ids across nested compositions with a compile-time
srcnow get a document-uniquedata-hf-render-idand both clips render.The residual:
<video id="clip" src="">plusel.src = urlin the scene script. Legal per file,checkclean. The static parse skips emptysrc, so those clips exist only in the browser snapshot. That snapshot still keys by author id. After inline, last write wins:data-media-start="10") gets scene B’s window — footage from ~40s.data-media-start="40") gets nothing injected — blank panel.Scene chrome still paints. Preview is correct (each scene’s script is scoped). Export disagrees.
#3342stamps render ids only when a playable source is already on the element, which is why this path never got one. Nativeurl(#…)/<use>is a different hole (#3490).Link to reproduction
https://github.com/ArcadeHQ/hyperframes-repros/tree/patch/runtime-src-duplicate-ids
Steps to reproduce
patch/runtime-src-duplicate-ids.npx hyperframes@latest check— 0 errors (duplicate ids across files are allowed).npx hyperframes@latest render . -f 10.snapshots/has actual vs expected frames.Control: rename scene B’s video id to
clip-b(and its script selector). Both windows render correctly.Expected behavior
Scene A shows the counter around 10–14. Scene B shows it around 44–48. Same as preview.
Actual behavior
On
hyperframes@0.8.15(latest):data-media-start).Environment
Additional context
The source is a synthetic
ffmpeg testsrcclip with a burnt-in seconds counter, so the wrong window is readable off the frame. Related, not the same: #3340 (staticsrc, fixed by render keys), #3490 (SVGurl(#)/<use>).