Skip to content

fix(registry): caption components group a replaced transcript instead of crashing - #7690

Open
wonjangcloud9 wants to merge 2 commits into
heygen-com:mainfrom
wonjangcloud9:fix/caption-highlight-groups
Open

wonjangcloud9 wants to merge 2 commits into
heygen-com:mainfrom
wonjangcloud9:fix/caption-highlight-groups

Conversation

@wonjangcloud9

Copy link
Copy Markdown
Contributor

Context: I've been using HyperFrames every day for the past two weeks to make Korean Shorts and long-form videos, and it's been great to work with. This PR is one of a batch of fixes for things I ran into along the way, so you'll see several PRs from me at once — sorry for the pile-up, and thanks for your patience. Each one is reproduced on current main, independent of the others, and can be reviewed, merged or closed on its own.

What

caption-highlight, caption-clip-wipe and caption-particle-burst no longer crash when you replace their WORDS with your own transcript. Their hand-tuned word groups are kept for the demo transcript (frames are byte-identical), and any other transcript is grouped by the same buildGroups that caption-glitch-rgb already uses.

Why

The three components group words with a hard-coded list of index ranges tuned for the 28-word demo:

var RAW_GROUPS = [[0, 3], [4, 7], [8, 8], [9, 12], [13, 15], [16, 16], [17, 19], [20, 22], [23, 24], [25, 27]];
var GROUPS = RAW_GROUPS.map(function (pair, gi) { ... WORDS[RAW_GROUPS[gi + 1][0]].start ... WORDS[we].end ... });

hyperframes add caption-highlight prints "paste from compositions/components/caption-highlight.html into your composition", and the obvious edit is to swap WORDS for your transcript. With a 15-word Korean transcript, WORDS[16] is undefined and the script throws before registering its timeline:

$ hyperframes check --no-cache --json
console_error  [HyperFrames] composition script error: caption-highlight TypeError: Cannot read properties of undefined (reading 'start')
ok: false

and the snapshot shows no captions at all. A longer transcript fails differently: words past index 27 are silently never shown.

Related work

No existing issue or PR on the index ranges. #2107 lists the caption components for unrelated reasons (placeholder <video>, contrast warnings); #6792 fixed their last-group end time and is unaffected.

How

In each of the three files:

// Hand-tuned for the demo WORDS; a replaced transcript is grouped by buildGroups instead.
var DEMO_GROUPS = [ /* unchanged ranges */ ];
function buildGroups(words) { /* verbatim from caption-glitch-rgb */ }
function tilesWords(groups, words) { /* ranges are contiguous from 0 and end at words.length - 1 */ }
var RAW_GROUPS = tilesWords(DEMO_GROUPS, WORDS) ? DEMO_GROUPS : buildGroups(WORDS);

Everything below RAW_GROUPS is untouched. buildGroups breaks after sentence punctuation, a gap over 0.28 s, 4 words or ~21 characters, so it is not a byte-for-byte match for the hand-tuned demo grouping, which is why the demo keeps its own ranges.

Derived catalog files (docs/catalog/components/*.mdx, payloads) are left for the publish PR; bun run check:catalog-drift reports "Catalog sources generate successfully".

Not changed: caption-clip-wipe and caption-particle-burst also keep a KEYWORDS set of demo word indices for their accent styling. With another transcript it accents whichever words sit at those indices; that is cosmetic and does not throw, so I left it out of this fix.

Test plan

  • New packages/cli/src/registry/captionWordGroups.test.ts (plain unit test; happy-dom DOM + a no-op GSAP timeline, runs the component's own inline script): for each of the three components, (1) the demo transcript still yields group sizes [4,4,1,4,3,1,3,3,2,3], (2) a 15-word Korean transcript runs without throwing and every word lands in a group. On main's components (2) fails 3/3 with TypeError: Cannot read properties of undefined (reading 'start'); with the fix 6/6 pass. src/registry/ unit tests 269 passed; captionLastGroup.chromium.test.ts passes.
  • Real CLI, project with caption-highlight mounted and WORDS swapped for 15 Korean words: main → check exit 1, console_error … reading 'start', snapshot at 1 / 3.2 / 6.6 s shows no captions; fixed component → check exit 0 (ok: true, only audio_none info), snapshot shows 오늘은 정말 특별한 날이에요. / 우리가 함께 만든 영상을 / 끝까지 봐 주세요. with the highlight sweep.
  • Demo unchanged: snapshot of the unmodified component at 0.5, 1.5, 2.3, 3.4, 5.2, 7.5 s on main and on this branch — all 7 PNGs have identical SHA-1s.
  • Documentation updated — n/a
  • Comments follow CONTRIBUTING.md "Comments"
  • Gates: oxlint, oxfmt, typecheck, fallow, comment ratchet — pass.

🤖 Generated with Claude Code

… of crashing

caption-highlight, caption-clip-wipe and caption-particle-burst grouped
their words with hand-written index ranges ([0,3] ... [25,27]) tuned for
the 28-word demo transcript. Replacing WORDS with a shorter one, as their
install snippet invites, read WORDS[16].start of undefined and the whole
caption track disappeared (page_error "Cannot read properties of undefined
(reading 'start')"). The hand-tuned ranges now apply only when they cover
WORDS exactly; any other transcript is grouped by the buildGroups function
caption-glitch-rgb already uses. The demo renders byte-identical frames.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@miguel-heygen miguel-heygen left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified at 5645e9b: the bug reproduces on main, and the new tests fail without the fix and pass with it. Required CI is green.

…egex

Parse the component with script execution disabled and take the inline
script from the parsed <script> elements, so the test no longer strips
tags with a regex (CodeQL js/bad-tag-filter,
js/incomplete-multi-character-sanitization).
@wonjangcloud9

wonjangcloud9 commented Nov 15, 2026 •

Copy link
Copy Markdown
Contributor Author

Thanks again for the CodeQL fix in baa93e4a and for the review! Sorry about the comment I posted here earlier. It went out in a strange form while I was away from my desk for a moment, so please disregard it.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants