Describe the bug
The shipped decision-tree example renders a 10-second video containing 2 unique
frames, and both quality gates report success while it happens.
Two defects, and the second is the serious one:
registry/examples/decision-tree/compositions/decision_tree.html:388 reads
tl.labels["hold5"]. At render time tl.labels is undefined, so the composition
script throws and the timeline is never built.
- Nothing fails.
check exits 0 and prints "Check passed". render logs the
TypeError, then logs sub_timeline_readiness_timeout after waiting 45 seconds,
then writes the mp4 and exits 0. A user following the quickstart gets a green
check, a green render, and a still image.
Anyone starting from this example hits it on their first render.
Steps to reproduce
npx --yes hyperframes@0.8.2 init decision-tree --non-interactive --example=decision-tree
cd decision-tree
npm run check # exits 0, "Check passed"
npm run render -- --quality draft --output renders/dt.mp4 # exits 0
# count unique frames in the result
mkdir -p /tmp/dtf && ffmpeg -v error -i renders/dt.mp4 -vf fps=1 /tmp/dtf/f%03d.png
ls /tmp/dtf | wc -l # 10 sampled
md5 -q /tmp/dtf/*.png | sort -u | wc -l # 2 unique
Expected behavior
The example renders its intended animation. Failing that, a composition script that
throws, or a sub-composition timeline that never registers, fails the render loudly
instead of producing a near-static file with a zero exit code.
Actual behavior
check:
0 error(s), 1 warning(s), 1 info(s)
Motion ◇ 0 errors, 0 warnings
Contrast ◇ 37/37 text checks pass WCAG AA
◇ Check passed
render:
[Browser:ERROR] [Compiler] Composition script failed decision-tree TypeError: Cannot read properties of undefined (reading 'hold5')
[FrameCapture] Sub-composition timelines not registered after 45000ms: decision-tree. ...
[FrameCapture:sub_timeline_readiness_timeout] Sub-composition timelines did not become ready within 45000ms { timeoutMs: 45000 }
[INFO] Calibration complete, estimated cost: 22ms/frame (p95)
The TypeError repeats during capture. The render then completes normally.
Output: 10.000000s, 193338 bytes, and sampling at 1 fps yields two distinct images —
one held for the first 8 samples, another for the last 2.
The failing code
// registry/examples/decision-tree/compositions/decision_tree.html:384
tl.addLabel("hold5", "+=0.2");
// :388
const typingStart = tl.labels["hold5"];
addLabel does not throw; the subsequent read of tl.labels does, so tl.labels is
undefined on the render path specifically. I have not determined why — that is worth
establishing before fixing, because if the timeline object exposed during render does
not carry labels, then every composition that reads a label position is affected and
this example is just the one we happen to ship.
Why the gate half matters more than the example
Fixing the example alone would close the symptom and leave the hole. Today a
composition script can throw on every frame, a sub-composition timeline can time out
after 45 seconds, and the pipeline still reports success. Both of those are already
detected and logged — they simply are not wired to an exit code.
Concretely worth deciding:
- A
[Compiler] Composition script failed error should fail the render, or at minimum
fail it under --strict, rather than only appearing in the log.
sub_timeline_readiness_timeout after a full 45-second wait is not a soft condition.
If a composition legitimately has no GSAP timelines it can declare data-no-timeline,
which is what that opt-out exists for, so reaching the timeout means something is
genuinely wrong.
Environment
hyperframes 0.8.2 (pinned by the scaffold; latest 0.8.3)
Node.js v22.23.1 (darwin arm64)
Capture drawelement -> beginframe, --quality draft, 6 workers
Describe the bug
The shipped
decision-treeexample renders a 10-second video containing 2 uniqueframes, and both quality gates report success while it happens.
Two defects, and the second is the serious one:
registry/examples/decision-tree/compositions/decision_tree.html:388readstl.labels["hold5"]. At render timetl.labelsis undefined, so the compositionscript throws and the timeline is never built.
checkexits 0 and prints "Check passed".renderlogs theTypeError, then logs
sub_timeline_readiness_timeoutafter waiting 45 seconds,then writes the mp4 and exits 0. A user following the quickstart gets a green
check, a green render, and a still image.
Anyone starting from this example hits it on their first render.
Steps to reproduce
Expected behavior
The example renders its intended animation. Failing that, a composition script that
throws, or a sub-composition timeline that never registers, fails the render loudly
instead of producing a near-static file with a zero exit code.
Actual behavior
check:render:The TypeError repeats during capture. The render then completes normally.
Output: 10.000000s, 193338 bytes, and sampling at 1 fps yields two distinct images —
one held for the first 8 samples, another for the last 2.
The failing code
addLabeldoes not throw; the subsequent read oftl.labelsdoes, sotl.labelsisundefined on the render path specifically. I have not determined why — that is worth
establishing before fixing, because if the timeline object exposed during render does
not carry
labels, then every composition that reads a label position is affected andthis example is just the one we happen to ship.
Why the gate half matters more than the example
Fixing the example alone would close the symptom and leave the hole. Today a
composition script can throw on every frame, a sub-composition timeline can time out
after 45 seconds, and the pipeline still reports success. Both of those are already
detected and logged — they simply are not wired to an exit code.
Concretely worth deciding:
[Compiler] Composition script failederror should fail the render, or at minimumfail it under
--strict, rather than only appearing in the log.sub_timeline_readiness_timeoutafter a full 45-second wait is not a soft condition.If a composition legitimately has no GSAP timelines it can declare
data-no-timeline,which is what that opt-out exists for, so reaching the timeout means something is
genuinely wrong.
Environment