Skip to content

fix(core): keep bundled HTML under V8's max string length - #6134

Merged
jrusso1020 merged 1 commit into
heygen-com:mainfrom
cauyxy:fix/bundler-inline-size-cap
Oct 24, 2026
Merged

jrusso1020 merged 1 commit into
heygen-com:mainfrom
cauyxy:fix/bundler-inline-size-cap

Conversation

@cauyxy

@cauyxy cauyxy commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

What

bundleToSingleHtml stops inlining data URLs once the bundle has inlined 256 MB of them. References past that point keep their relative URL.

Why

Each asset under 2 MB is inlined once per reference, so an image used hundreds of times can push the bundle past V8's max string length and check/snapshot/render throw RangeError: Invalid string length. The per-asset limit cannot prevent this; only a limit on the total can.

Related work

Fixes #6133. No overlapping open PRs found.

How

createAssetInliner counts the characters it has inlined. Before returning a data URL that would exceed MAX_INLINED_BUNDLE_CHARS (256 MB, half of V8's limit, leaving room for the rest of the HTML), it warns once and returns null, so the reference falls through to its existing relative-URL path. Bundles under the cap are byte-for-byte unchanged.

Deduplicating (write each asset once and reference it) would also shrink normal bundles, but changes the output shape; this PR keeps to the crash. Happy to follow up with dedup if you prefer that direction.

Test plan

  • New test in htmlBundler.test.ts: 300 references to a 1.9 MB asset. Fails on main with RangeError: Invalid string length; passes here, with some references inlined, the rest relative, and one warning.
  • All 187 packages/core tests, oxlint, oxfmt, typecheck and lefthook pre-commit pass.
  • Comments say why the cap exists and how to reproduce the crash.

@cauyxy
cauyxy force-pushed the fix/bundler-inline-size-cap branch from 7644f89 to fdf538f Compare October 23, 2026 14:32

@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.

Nice catch, and thank you for the first contribution here. Counting per reference rather than per asset is the right call, since that is what actually lands in the output string, and routing it through the one inliner means the srcset, CSS url() and LUT paths are all covered. The test goes through bundleToSingleHtml and genuinely fails without the cap.

Two optional notes, neither blocking: the budget latches once, so a small font after the overflowing image keeps its relative URL too, which is worth a word in the comment since it is deliberate. And the test holds a 266 MB string and splits it twice. Making the cap injectable would let the same assertions run on a few MB.

@jrusso1020 jrusso1020 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.

Approving. The crash is real: on main, createAssetInliner caches one data URL per asset but returns it for every reference, so an image under the 2 MB per-asset cap that is used hundreds of times builds a string past V8's limit and every caller of bundleToSingleHtml (check, snapshot, layout, studio preview, inspector) throws RangeError: Invalid string length.

A bundle-wide budget is the right shape for this, and it is placed at the one function every inlining path goes through (img/src, srcset, CSS url(), inline styles and LUTs), so nothing sidesteps it. Past the budget a reference keeps its relative URL, which is the same fallback the per-asset cap already uses, with one warning. Bundles under 256 MB are unchanged.

I ran the new test on main without the fix and it fails with RangeError: Invalid string length. With the fix the whole htmlBundler.test.ts file passes, 187/187.

The one red check, Studio edit accuracy shard 1, was cancelled in its browser ensure step after 25 minutes, so it is an infra timeout and not this change.

Need: yes, a repeated asset crashes every bundle consumer · Size: ok · Reuse: extends the existing per-asset inline cap in the same inliner · Simpler: already minimal; the dedup the author mentions would also shrink normal bundles but changes output shape, fine as a follow-up

— Rames

@jrusso1020
jrusso1020 added this pull request to the merge queue Oct 24, 2026
Merged via the queue into heygen-com:main with commit 879d735 Oct 24, 2026
77 of 78 checks passed
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.

bundleToSingleHtml throws "RangeError: Invalid string length" when one image is referenced many times

3 participants