runtime: startResolver only checks the immediate parent for composition attributes, so a mount wrapped by any element is seeked on the root clock
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Newbie friendliness
- 74/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- typescript
- Domain
- web-dev
Research direction
Start in packages/core/src/runtime/startResolver.ts, focusing on the no-authored-start branch, then review packages/core/src/runtime/startResolver.test.ts and its existing resolver setup. Add the neutral-wrapper regression matrix for the three composition markers, run bun run --cwd packages/core test src/runtime/startResolver.test.ts, and verify the accepted boundary and timing cases remain intact.
Written by the indexing model from the issue text.
Description
Found while exporting After Effects comps to data-vfx-chain hosts (hyperframes-ae-mcp, findings §Task 3.14, 2026-09-23).
Symptom. A sub-composition mount whose data-composition-src element sits under a wrapper (here <canvas layoutsubtree class="hf-vfx-src"> > .hf-vfx-in[data-composition-src]) resolves its start to 0 and is seeked on the root clock. Once root time passes the sub-comp's own duration, its layers go visibility: hidden, and drawElementImage returns a transparent bitmap with no error. On retro-wave the mounted Logo comp painted 17,874 / 22,633 / 0 / 0 opaque px at root t = 7.3 / 8.5 / 10.444 / 12.5 s with byte-identical geometry; the threshold is exactly the sub-comp's 10.01 s duration.
Cause. startResolver's walk-up is one level: it fires only if the immediate parent carries data-composition-src / -id / -file. A canvas or any exporter/author wrapper between them breaks the chain.
Ask. Use a closest()-style walk (nearest ancestor carrying a composition marker, stopping at the composition root) so any wrapper is safe. The exporter works around it today by copying data-start/data-duration onto the wrapped element.
Method worth keeping. A DOM probe injected into a copy of the emitted project (rAF overlay drawn into the snapshot PNG, no CDP, no runtime patch) made the per-time paint counts observable under hyperframes snapshot.
Contribution brief — September 23, 2026
Confirmed behavior
Reproduced using the actual createRuntimeStartTimeResolver in Chrome 150.0.7871.24 at source fa4261bee (0.8.68), then rechecked against main 86fa10ced4297bfd9f4fe67b6767afae7a07fd3c (0.8.69): the resolver and its relevant dependencies are unchanged. For a host starting at 5 seconds and an untimed inner composition root:
| Host marker | Direct child | One neutral wrapper | Two neutral wrappers |
|---|---|---|---|
data-composition-src |
5 | 0 | 0 |
data-composition-id |
5 | 0 | 0 |
data-composition-file |
5 | 0 | 0 |
All cases should preserve the same host start. This reproduces the resolver defect; the complete AE export/snapshot/render path has not been rerun.
Minimal regression fixture
Add a test in the existing packages/core/src/runtime/startResolver.test.ts suite, where the resolver import, jsdom environment and cleanup already exist:
it("preserves the host start across a neutral wrapper", () => {
document.body.innerHTML = `
<div data-composition-id="root" data-start="0">
<div data-composition-src="child.html" data-start="5">
<section><div id="inner" data-composition-id="child"></div></section>
</div>
</div>`;
const inner = document.getElementById("inner");
if (!inner) throw new Error("Missing fixture root");
const resolver = createRuntimeStartTimeResolver({});
expect(resolver.resolveStartForElement(inner)).toBe(5);
});
The browser probe returns 0 for this shape, versus 5 when the section is removed. No media files or exporter are needed for this isolated regression. Expand the test to the full matrix rather than only covering one marker.
Accepted scope and starting points
In the no-authored-start branch of startResolver.ts, find the nearest enclosing composition host across neutral wrappers while preserving composition boundaries and existing timing semantics. Extend startResolver.test.ts.
This is medium work because host offsets, explicit timing, and boundary semantics interact. Keep the fix limited to host-start resolution; do not redesign VFX, playback clocks or media scheduling.
Acceptance checks
- All nine combinations above resolve to 5; the six wrapper cases fail before the fix.
- Stop at the nearest composition boundary; do not use an outer host or sibling clock.
- Preserve explicit authored starts, named/anonymous hosts, reference expressions and unresolved fallbacks.
- After following CONTRIBUTING.md, run
bun run --cwd packages/core test src/runtime/startResolver.test.ts, then the relevant broader core/runtime tests. Use the package's Vitest runner, not barebun test. - Exercise a mounted-composition snapshot/render regression before merge; unit success alone is not end-to-end proof. Include the fixture and observed timing in the PR.
- Lint and format changed files under the repository guidelines.
Availability and related work
On September 23 there were no assignments, claim comments or directly linked implementation PRs. PR #3826 touches this resolver, but its inspected diff only adds resolveLocalStartForElement; it does not repair this ancestor walk. PR #4330 is adjacent VFX work. Recheck both before starting and coordinate any shared-file changes. Comment with the intended approach before beginning so a maintainer can coordinate ownership.
triage/ready describes this accepted, specified scope. Reviewer/mentor ownership is still being confirmed; this brief does not assign anyone or promise newcomer mentoring.
- Dominant language
- TypeScript
- Stars
- 54.1k
- Forks
- 4.9k
- Avg merge
- 17h 15m
- Merged PRs (30d)
- 737
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from heygen-com/hyperframes
-
motion-graphics: point the Builder at hyperframes-creative's motion-principles.mdPossibly taken @miguel-heygen claimed this today. Openenhancement triage/needs-triage
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
heygen-com/hyperframes#4944 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
heygen-com/hyperframes#4702 · 1 comment · 1 reaction ·
Maintainers usually reply within 1 day
-
Studio catalog prompt editor has no accessible namePossibly taken @lorenzozanee claimed this 10 days ago. Openbug difficulty/easy triage/ready
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
heygen-com/hyperframes#4384 ·
Maintainers usually reply within 1 day
-
lint: validate composition variables declared on supported root elementsMay be free again A pull request for this issue was closed without being merged. Openbug difficulty/easy triage/ready
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
heygen-com/hyperframes#4383 ·
Maintainers usually reply within 1 day
-
lint: report AVIF/M4A media-kind mismatches consistently with JPEG/MP3May be free again A pull request for this issue was closed without being merged. Openbug difficulty/easy triage/ready
Difficulty 2/5 1-3 hours Newbie friendliness 91/100
heygen-com/hyperframes#4382 · 1 comment ·
Maintainers usually reply within 1 day
All issues in heygen-com/hyperframes
Similar issues
-
check:passed streams:add
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
Maintainers usually reply within 1 day
-
[Bug] The shared instance selector's placeholder and no-match text ignore the display languagePossibly taken A pull request linked to this issue is open or already merged. Open
Difficulty 2/5 1-3 hours Newbie friendliness 90/100
apache/rocketmq-dashboard#5561 ·
Maintainers usually reply within 3 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
CopilotKit/OpenDots#69 ·
Maintainers usually reply within 1 day
-
sendDefaultPii is reported as deprecated on ReactNativeOptions although dataCollection is hiddenOpenBug React-Native Waiting for: Product Owner
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
getsentry/sentry-react-native#6830 · 1 comment ·
Maintainers usually reply within 1 day
-
OSCI'26
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
GauravKarakoti/SecureFlow#1215 ·
Maintainers usually reply within 1 day