Repository navigation
fix(cli): Recognize debug ID snippets from Oxc and React Native Metro - #2268
Merged
BYK merged 4 commits intoNov 14, 2026
Merged
Conversation
`sourcemap inject` and `sourcemap upload` decide whether a file already registers its debug ID by matching the registry write, and only accepted a quoted ID. Oxc, the minifier in Vite 8, rewrites a bundler plugin's `e._sentryDebugIds[n]="<id>"` to a template literal, so the check missed it and a second snippet was prepended on a new first line. Through @sentry/vite-plugin this shifted every uploaded source map one line ahead of the deployed chunk, because the plugin uploads prepared copies and the deployed files are not touched. Accept backticks wherever a quote is accepted. Fixes getsentry#2267 Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Oxc also folds Turbopack's inline registry initialization,
`(e._debugIds||(e._debugIds={}))[n]`, into a logical assignment,
`(e._debugIds||={})[n]`. Accept that form, and `??=`, so a Turbopack
chunk minified by Oxc is not given a second snippet either.
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Each form the registration check accepts now has a test that fails when that form is removed: `??=` and a bracketed registry name in backticks had none. Add near misses (an interpolated template, `&&=`, and `==`) that must still get a snippet, since this check gates skipping injection. Co-Authored-By: BYK <126780+BYK@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Looks good to me, and thanks for the thorough write-up @esetnik. The bug still reproduces on main, and both new cases fail there and pass here. I also minified the bundler plugin, CLI, legacy CLI and Turbopack snippets with oxc-minify, rolldown, terser, esbuild and swc, and every output is recognized and registers its ID at runtime. Timing the regex on 16 MB near-miss inputs showed it stays linear.
This check decides whether injection is skipped, so I pushed one test-only commit (3b36a4a):
??=and a bracketed registry name in backticks were accepted, but removing either one left every test passing. Each now has a case in the existing table, and each new case fails when its branch is reverted.- Added three near misses that must still get a snippet: an interpolated template,
&&=, and==. A version of the regex that also accepted&&=fails these.
The React Native Metro plugin registers on a global variable, `_sentryDebugIds[stack]="<id>"`, not on a property of the global object. The check required a `.` or a bracketed name before the registry, so a Metro bundle was given a second snippet as well. This one does not depend on a minifier. Accept the registry name when it is not part of a longer identifier. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
BYK
approved these changes
Nov 14, 2026
BYK
enabled auto-merge (squash)
November 14, 2026 19:21
This branch was previously deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #2267.
sentry sourcemap injectandsentry sourcemap uploadcheck whether a file already registers its debug ID by matching the registry write withDEBUGID_REGISTRATION_RE. Three forms that Sentry's own tools produce were not matched, so each got a second snippet on a new first line, with;prepended to the map'smappings:e._sentryDebugIds[n]="<id>"toe._sentryDebugIds[t]=`<id>`.||=. Oxc folds Turbopack's(e._debugIds||(e._debugIds={}))[n]into(e._debugIds||={})[t]._sentryDebugIds[stack]="<id>", with no object in front. This one needs no minifier.Through
@sentry/vite-plugin, the first shifts every uploaded source map one line ahead of the deployed chunk: the plugin uploads prepared copies, so the deployed files never get the extra line. Frames then resolve to the wrong function or fail withjs_invalid_sourcemap_location.Changes
One commit per form, all in
DEBUGID_REGISTRATION_RE:e[`_sentryDebugIds`]).||=or??=.my_sentryDebugIds[t]="<id>"still gets a snippet.Tests, in the existing tables in
inject.test.ts(each runs for external and inline maps):templateLiteralsandturbopackLogicalAssignmentas Oxc emits them, andreactNativeMetroas the Metro plugin emits it.longerIdentifier.??=and the backticked bracket form and adds three more near misses.Verification
Project checks on the branch head (
db3441c), run locally on macOS:pnpm run tsc: passes.pnpm run lintat the repo root (oxlint, oxfmt, ast-grep, workspace dependency check): passes.pnpm run test:e2einpackages/cli: 206 passed, 1 failed, 3 skipped. The failure istelemetry-exit, a timing assertion (3.08 s against a 2 s limit) while the suite was running; it passes on its own on this branch and onmain.inject.test.ts: 72 passed.templateLiteralsandturbopackLogicalAssignmentwithout the first two commits,reactNativeMetrowithout the third, andlongerIdentifierif the identifier boundary is dropped.pnpm run testinpackages/cli: 13,170 passed, 28 failed, 61 skipped. None of the failures is in sourcemap code, and they are not caused by this change: the same 28, in the same six files, fail on unmodifiedmain(f8464f8) on this machine:debug-files/upload,build/car-extract.integration,build/zip-writer,delta-upgrade.mocked,install-scriptandtime-range.A wider matrix, run locally through
injectDirectoryon the branch head and not committed (150 cases):unsafe, single quotes, beautify, no mangle), swc (default, ES2022 with 2 passes, no compress), esbuild (default,esnext,es2015, syntax only) and Oxc via rolldown 1.2.19 (default, no mangle, no compress,es2015,es2020,esnext, whitespace kept). Each file must be left unchanged and register its ID once at runtime.var _sentryDebugIdstoe, so the file no longer registers under the registry name and injecting a snippet is the correct result. With mangling off the Metro snippet is left unchanged.sourceMappingURL, no trailing newline, CRLF, a hashbang first, a"use strict"directive first, the snippet after other code, an uppercase ID, a 32-hex ID, the ID only in the map (debug_idordebugId), the ID only in the comment, a legacy//@ sourceMappingURL, and an inline map with and without the comment.Checked against the regex only, on the branch head:
uglify-js 3.19.3 and Bun 1.4.4 (
--minify,--minify-syntax,--minify-whitespace) leave the bundler plugin, CLI, formatted, Turbopack and esbuild-plugin snippets recognisable.Inputs it must reject: mismatched quotes, a registry read that is not a write,
||={a:1}, and&&=.Closure Compiler v20240317:
WHITESPACE_ONLYandSIMPLEleave all six snippet forms recognisable.ADVANCEDrenames the_sentryDebugIdsproperty (tog), so the bundle no longer registers under the registry name and injecting is correct.A real Metro bundle:
metro0.88.0 withcreateSentryMetroSerializerfrom@sentry/react-native8.35.0, built with--minify trueand--minify false. Both bundles carry the bare-global snippet and a//# debugId=comment.sentry@0.45.0sentry@0.49.0main(f8464f8), from sourceNot tested: a full React Native app build (the bundle above has a plain JS entry file, with no
react-nativeruntime).🤖 Generated with Claude Code