Skip to content

fix(sourcemap): crash finalizing bundles with more than 65,535 files (CLI-39Q) - #1654

Draft
cursor[bot] wants to merge 2 commits into
mainfrom
cursor/fix-sourcemap-zip64-8f7f
Draft

cursor[bot] wants to merge 2 commits into
mainfrom
cursor/fix-sourcemap-zip64-8f7f

Conversation

@cursor

@cursor cursor Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Fixes CLI-39Q

Sentry issue: CLI-39Q: RangeError: The value of "value" is out of range. It must be >= 0 and <= 65535. Received 72983 (escalating, ~250 events, all on 0.45.0, sourcemap upload).

Root cause: ZipWriter.finalize() in src/lib/sourcemap/zip.ts writes this.entries.length directly into the classic end-of-central-directory record's 16-bit entry-count fields, so Buffer.writeUInt16LE throws once an artifact bundle has more than 65,535 entries.

Reproduction: run sentry sourcemap upload <dir> on a directory with more than ~32.7k JS + sourcemap pairs (each pair is two bundle entries, plus manifest.json). In the reported events this was a large Next.js .next/server build. A direct repro is ZipWriter.create(), then 65,536 addEntry() calls, then finalize(); 65,535 entries still work.

Fix: when the entry count exceeds 0xFFFF, finalize() now writes the ZIP64 end-of-central-directory record and locator right before the classic record, and caps the classic count fields at 0xFFFF (APPNOTE 4.4.1.4). The legacy Rust CLI's zip crate does the same thing. Archives at or below the limit come out byte-for-byte unchanged.

Verification

  • New regression test in test/lib/sourcemap/zip.test.ts writes 65,536 entries and checks the ZIP64 record, the locator offset, the capped classic fields, and unzip -t. Without the fix it fails with the exact CLI-39Q RangeError.
  • I checked the 65,536- and 72,983-entry archives (with the SYSB prefix) by hand using unzip -t/unzip -l and Python's zipfile (the reader Sentry's artifact-bundle assembly uses). Both list every entry and read back the content, and the locator offset points exactly at the ZIP64 record.
  • biome check and tsc --noEmit are clean. The full Vitest unit suite passes (10,163 tests) apart from test/lib/delta-upgrade.mocked.test.ts, which fails the same way on main without this change.

Out of scope: src/lib/build/zip-writer.ts (build upload) has the same 16-bit limit, but it's a separate code path with no reported events, so it belongs in its own PR.

Open in Web View Automation 

…(Sentry CLI-39Q)

ZipWriter.finalize() wrote the entry count straight into the classic
end-of-central-directory record's 16-bit fields, so `sourcemap upload`
threw `RangeError: The value of "value" is out of range` for any upload
directory with more than 65,535 bundle entries (e.g. a large Next.js
`.next/server` build).

When the count overflows, write the ZIP64 end-of-central-directory
record and locator before the classic record and saturate the classic
count fields at 0xFFFF, as APPNOTE 4.4.1.4 prescribes. Archives at or
below the limit are byte-for-byte unchanged.

Fixes CLI-39Q

Co-authored-by: Miguel Betegón <miguelbetegongarcia@gmail.com>
@vercel

vercel Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
cli Ready Ready Preview Oct 5, 2026 12:24pm UTC
1 Skipped Deployment
Project Deployment Actions Updated
sentry-local Skipped Skipped Oct 5, 2026 12:24pm UTC

Request Review

This branch was successfully deployed

1 active and 1 inactive deployments
Preview – cli — 536b641c Deployed Oct 5, 2026 by vercel[bot]
Preview – sentry-local — 536b641c Deployed Oct 5, 2026 by vercel[bot]
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.

1 participant