Skip to content

fix: Prevent Metro serializer crash on non-standard serializer output - #6652

Open
antonis wants to merge 3 commits into
mainfrom
fix/metro-serializer-non-standard-output
Open

fix: Prevent Metro serializer crash on non-standard serializer output#6652
antonis wants to merge 3 commits into
mainfrom
fix/metro-serializer-non-standard-output

Conversation

@antonis

@antonis antonis commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

📢 Type of change

  • Bugfix
  • New feature
  • Enhancement
  • Refactoring

📜 Description

The Metro serializer used 'map' in serializerResult to decide whether the wrapped serializer returned a { code, map } bundle. Because Array.prototype.map is inherited, 'map' in anyArray is always true — so when the wrapped serializer returns an array (as Expo's serializer does for static/EAS Update exports), the code took the bundle branch and returned { code: undefined, map: undefined }. determineDebugIdFromBundleSource(undefined) then called undefined.match(...) and crashed the bundler:

TypeError: Cannot read properties of undefined (reading 'match')
    at determineDebugIdFromBundleSource (.../tools/utils.js)

Changes:

  • Replace the unsound 'map' in result check with a positive one: the result is treated as a bundle only when it's a non-array object with a string code.
  • When the (already awaited) result is not a standard { code, map } bundle, return it untouched instead of crashing. Debug IDs for Expo static exports are handled by Expo's own serializer.

💡 Motivation and Context

Fixes #6650. All withSentryConfig users doing Expo static / EAS Update (OTA) bundling hit this crash on @sentry/react-native 8.23.0 and 8.24.0. The only workaround was disabling withSentryConfig, which removes Debug ID injection and produces unreadable stack traces in Sentry.

💚 How did you test it?

Added two regression tests in sentryMetroSerializer.test.ts (a serializer returning an array, and one returning a promise that resolves to an array). Both reproduce the exact TypeError on main and pass with the fix. Full tools test suite passes (336 tests); yarn build:sdk and lint are clean.

📝 Checklist

  • I added tests to verify changes.
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled.
  • I updated the docs if needed.
  • I updated the wizard if needed.
  • All tests passing.
  • Public API changes reviewed by another Mobile SDK team member or implemented according to the develop docs spec.
  • No breaking changes.

🔮 Next steps

In the pass-through path the Sentry Debug ID module is still prepended and handed to the wrapped serializer (unchanged behavior), so Expo static bundles may contain that module with an unreplaced __debug_id_place_holder__. It cannot be mis-detected as a real Debug ID (the sentry-dbid-<uuid> regex rejects it), but a follow-up should confirm against a live eas update export whether that module should be suppressed when the output is non-standard.

The Metro serializer used `'map' in serializerResult` to detect a
`{ code, map }` bundle. For arrays that check is always true because of
`Array.prototype.map`, so an array result (e.g. Expo's static/EAS Update
export) yielded `{ code: undefined }` and crashed in
`determineDebugIdFromBundleSource` with "Cannot read properties of
undefined (reading 'match')".

Detect a bundle with a positive check (object, not array, string `code`)
and pass non-standard output through untouched instead of crashing.

Fixes #6650

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Semver Impact of This PR

None (no version bump detected)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


  • fix: Prevent Metro serializer crash on non-standard serializer output by antonis in #6652
  • chore: Add supply-chain provenance guidance to agent skills by antonis in #6644
  • fix(tracing): Keep launch-screen TTID/TTFD anchored to navigation on delayed first navigation by antonis in #6626
  • chore: Extend agents.toml and .agents/skills (Extend Warden setup #6637) by antonis in #6643
  • chore(sample): Bump React Native sample to 0.87.0 by antonis in #6617
  • fix(core): Resolve Metro from project root for source map generation by antonis in #6625
  • docs(sdk-versions): Add 8.14.3 row to SDK-VERSIONS.md by antonis in #6649
  • chore(deps): update Maestro to v2.10.0 by github-actions in #6641
  • chore(deps): update JavaScript SDK to v10.73.0 by github-actions in #6642
  • test(ios): Speed up sentry-xcode-scripts tests by antonis in #6633
  • fix: Update recommended vscode extensions by antonis in #6640
  • chore(deps): bump actions/setup-java from 5.7.0 to 6.0.0 by dependabot in #6636
  • chore(deps): bump the codeql-action group with 3 updates by dependabot in #6635
  • chore(deps): update JavaScript SDK to v10.72.0 by github-actions in #6634
  • chore(e2e): Bump E2E tests to React Native 0.87.0 by antonis in #6616
  • chore(deps): update CLI to v3.7.0 by github-actions in #6632
  • feat(tracing): Copy app start vitals onto standalone children by buenaflor in #6631
  • chore(deps): update Cocoa SDK to v9.26.1 by github-actions in #6623
  • fix(ios): Force-load the Sentry static archive to keep ObjC category methods by antonis in #6615
  • feat(core): Forward feature flag evaluations to the native SDKs by antonis in #6613
  • chore(deps): update Android SDK to v8.54.0 by github-actions in #6624
  • chore(deps): update Sentry Android Gradle Plugin to v6.20.0 by github-actions in #6627

🤖 This preview updates automatically when you update the PR.

@antonis antonis added the ready-to-merge Triggers the full CI test suite label Sep 1, 2026
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@antonis

antonis commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

@cursor review

@antonis

antonis commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

@sentry review

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

The implementation now supports (and may return) non-standard serializer outputs, but the exported serializer types still only model standard { code, map }/string outputs, leaving behavior and TypeScript API inconsistent.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Fixes a Metro bundler crash in the Sentry Metro serializer when the wrapped serializer returns non-standard outputs (notably arrays from Expo static/EAS Update exports), by tightening bundle-shape detection and safely passing through unsupported result shapes.

Changes:

  • Replace the unsound 'map' in result bundle check with a stricter object-shape check (code must be a string and result must not be an array).
  • Pass through non-standard serializer outputs unchanged instead of attempting Debug ID injection and crashing.
  • Add regression tests covering array and promise-resolving-to-array serializer outputs; document the fix in the changelog.
File summaries
File Description
packages/core/src/js/tools/sentryMetroSerializer.ts Makes serializer result handling robust against non-standard outputs and avoids crashing on array results.
packages/core/test/tools/sentryMetroSerializer.test.ts Adds regression tests for array and async-array serializer outputs to prevent reintroducing the crash.
CHANGELOG.md Notes the fix in the Unreleased section for user visibility.
Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/core/src/js/tools/sentryMetroSerializer.ts

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit c67100a. Configure here.

@sentry

sentry Bot commented Sep 1, 2026

Copy link
Copy Markdown

📲 Install Builds

Android

🔗 App Name App ID Version Configuration
Sentry RN io.sentry.reactnative.sample 8.24.0 (104) Release

⚙️ sentry-react-native Build Distribution Settings

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Android (legacy) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 431.72 ms 452.00 ms 20.28 ms
Size 49.74 MiB 55.66 MiB 5.91 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
5a010b7+dirty 425.62 ms 469.38 ms 43.76 ms
1a5721e+dirty 424.07 ms 482.32 ms 58.25 ms
7d8c8bd+dirty 417.45 ms 462.10 ms 44.65 ms
27d9693+dirty 419.08 ms 469.12 ms 50.04 ms
6bbd2c7+dirty 421.43 ms 436.30 ms 14.88 ms
ef27341+dirty 412.94 ms 443.98 ms 31.04 ms
41d6254+dirty 424.45 ms 474.34 ms 49.89 ms
b9bebee+dirty 438.86 ms 452.21 ms 13.35 ms
3d536d1+dirty 524.34 ms 547.32 ms 22.98 ms
580fb5c+dirty 436.34 ms 471.63 ms 35.28 ms

App size

Revision Plain With Sentry Diff
5a010b7+dirty 48.30 MiB 53.58 MiB 5.28 MiB
1a5721e+dirty 49.74 MiB 55.09 MiB 5.34 MiB
7d8c8bd+dirty 48.30 MiB 53.54 MiB 5.23 MiB
27d9693+dirty 49.74 MiB 55.09 MiB 5.34 MiB
6bbd2c7+dirty 49.74 MiB 55.66 MiB 5.91 MiB
ef27341+dirty 48.30 MiB 53.54 MiB 5.24 MiB
41d6254+dirty 48.30 MiB 53.60 MiB 5.30 MiB
b9bebee+dirty 48.30 MiB 53.58 MiB 5.28 MiB
3d536d1+dirty 49.74 MiB 55.26 MiB 5.52 MiB
580fb5c+dirty 49.74 MiB 54.79 MiB 5.05 MiB

Previous results on branch: fix/metro-serializer-non-standard-output

Startup times

Revision Plain With Sentry Diff
041b578+dirty 447.90 ms 458.69 ms 10.79 ms

App size

Revision Plain With Sentry Diff
041b578+dirty 49.74 MiB 55.66 MiB 5.91 MiB

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

iOS (legacy) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 3865.04 ms 1227.53 ms -2637.51 ms
Size 5.08 MiB 6.80 MiB 1.72 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
68ae91b+dirty 3834.04 ms 1216.60 ms -2617.44 ms
0b5a379+dirty 3828.91 ms 1214.12 ms -2614.79 ms
f170ec3+dirty 3822.26 ms 1218.33 ms -2603.93 ms
68672fc+dirty 3841.58 ms 1228.89 ms -2612.69 ms
2c735cc+dirty 1229.67 ms 1221.50 ms -8.17 ms
b9bebee+dirty 3850.15 ms 1227.51 ms -2622.64 ms
a50b33d+dirty 1197.74 ms 1197.17 ms -0.57 ms
5569641+dirty 3839.22 ms 1231.30 ms -2607.91 ms
f9c1ed4+dirty 3833.98 ms 1226.30 ms -2607.68 ms
7ac3378+dirty 1213.37 ms 1218.15 ms 4.78 ms

App size

Revision Plain With Sentry Diff
68ae91b+dirty 4.98 MiB 6.46 MiB 1.48 MiB
0b5a379+dirty 5.15 MiB 6.70 MiB 1.54 MiB
f170ec3+dirty 5.15 MiB 6.69 MiB 1.53 MiB
68672fc+dirty 5.15 MiB 6.71 MiB 1.55 MiB
2c735cc+dirty 3.38 MiB 4.74 MiB 1.35 MiB
b9bebee+dirty 5.15 MiB 6.68 MiB 1.53 MiB
a50b33d+dirty 3.38 MiB 4.73 MiB 1.35 MiB
5569641+dirty 5.15 MiB 6.67 MiB 1.51 MiB
f9c1ed4+dirty 4.98 MiB 6.50 MiB 1.53 MiB
7ac3378+dirty 3.38 MiB 4.76 MiB 1.38 MiB

Previous results on branch: fix/metro-serializer-non-standard-output

Startup times

Revision Plain With Sentry Diff
041b578+dirty 3841.26 ms 1226.08 ms -2615.17 ms

App size

Revision Plain With Sentry Diff
041b578+dirty 5.08 MiB 6.80 MiB 1.72 MiB

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Android (new) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 429.05 ms 435.14 ms 6.09 ms
Size 49.74 MiB 55.66 MiB 5.91 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
c151573+dirty 485.39 ms 495.18 ms 9.79 ms
5c1e987+dirty 444.71 ms 475.13 ms 30.42 ms
04207c4+dirty 395.40 ms 456.55 ms 61.15 ms
3ce5254+dirty 373.90 ms 427.84 ms 53.94 ms
6176a94+dirty 403.58 ms 446.73 ms 43.15 ms
9474ead+dirty 432.18 ms 481.92 ms 49.73 ms
09a902f+dirty 423.02 ms 472.18 ms 49.16 ms
882f8ae+dirty 408.19 ms 435.86 ms 27.67 ms
1122a96+dirty 510.16 ms 542.00 ms 31.84 ms
7d6fd3a+dirty 435.06 ms 458.78 ms 23.72 ms

App size

Revision Plain With Sentry Diff
c151573+dirty 48.30 MiB 53.54 MiB 5.24 MiB
5c1e987+dirty 43.94 MiB 48.94 MiB 5.00 MiB
04207c4+dirty 43.94 MiB 48.98 MiB 5.04 MiB
3ce5254+dirty 43.94 MiB 48.98 MiB 5.04 MiB
6176a94+dirty 48.30 MiB 53.54 MiB 5.24 MiB
9474ead+dirty 48.30 MiB 53.61 MiB 5.30 MiB
09a902f+dirty 49.74 MiB 54.81 MiB 5.07 MiB
882f8ae+dirty 48.30 MiB 53.60 MiB 5.29 MiB
1122a96+dirty 48.30 MiB 53.54 MiB 5.24 MiB
7d6fd3a+dirty 43.94 MiB 49.00 MiB 5.06 MiB

Previous results on branch: fix/metro-serializer-non-standard-output

Startup times

Revision Plain With Sentry Diff
041b578+dirty 524.59 ms 586.36 ms 61.77 ms

App size

Revision Plain With Sentry Diff
041b578+dirty 49.74 MiB 55.66 MiB 5.91 MiB

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

iOS (new) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 3853.83 ms 1224.28 ms -2629.56 ms
Size 5.08 MiB 6.80 MiB 1.72 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
3b6e9f9+dirty 3822.77 ms 1208.00 ms -2614.77 ms
4e0b819+dirty 3828.96 ms 1205.64 ms -2623.32 ms
1e5d96d+dirty 3845.93 ms 1222.51 ms -2623.42 ms
0a9e622+dirty 3825.35 ms 1219.04 ms -2606.31 ms
5ca03f9+dirty 3873.76 ms 1236.26 ms -2637.51 ms
40c9884+dirty 3826.11 ms 1217.04 ms -2609.07 ms
57e0069+dirty 3842.23 ms 1210.00 ms -2632.23 ms
7ac3378+dirty 1202.35 ms 1198.31 ms -4.04 ms
20fbd51+dirty 3832.52 ms 1206.13 ms -2626.39 ms
822d35b+dirty 3841.52 ms 1221.75 ms -2619.77 ms

App size

Revision Plain With Sentry Diff
3b6e9f9+dirty 5.15 MiB 6.68 MiB 1.53 MiB
4e0b819+dirty 4.98 MiB 6.46 MiB 1.49 MiB
1e5d96d+dirty 4.98 MiB 6.46 MiB 1.49 MiB
0a9e622+dirty 4.98 MiB 6.51 MiB 1.53 MiB
5ca03f9+dirty 4.98 MiB 6.53 MiB 1.55 MiB
40c9884+dirty 4.98 MiB 6.51 MiB 1.53 MiB
57e0069+dirty 4.98 MiB 6.50 MiB 1.52 MiB
7ac3378+dirty 3.38 MiB 4.76 MiB 1.38 MiB
20fbd51+dirty 4.98 MiB 6.46 MiB 1.49 MiB
822d35b+dirty 4.98 MiB 6.50 MiB 1.53 MiB

Previous results on branch: fix/metro-serializer-non-standard-output

Startup times

Revision Plain With Sentry Diff
041b578+dirty 3842.63 ms 1228.23 ms -2614.40 ms

App size

Revision Plain With Sentry Diff
041b578+dirty 5.08 MiB 6.80 MiB 1.72 MiB

@antonis antonis removed the ready-to-merge Triggers the full CI test suite label Sep 2, 2026
@antonis antonis added the ready-to-merge Triggers the full CI test suite label Sep 2, 2026
@antonis
antonis marked this pull request as ready for review September 2, 2026 07:49

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

LGTM!

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

Labels

ready-to-merge Triggers the full CI test suite

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Metro serializer crash: 'map' in array always true via Array.prototype.map → serializerResult.code undefined in determineDebugIdFromBundleSource

3 participants