Skip to content

[@sentry/react-native/expo] Config plugin not applied during EAS Build cloud prebuild — source maps never upload, releases empty #6048

@eeromannermaa-create

Description

@eeromannermaa-create

What React Native libraries do you use?

Expo Router

Are you using sentry.io or on-premise?

sentry.io (SaS)

Are you using any other error monitoring solution alongside Sentry?

No

Other Error Monitoring Solution Name

N/A

@sentry/react-native SDK Version

8.9.1

How does your development environment look like?

Q: What React Native libraries do you use?
A: EXPO /EXPO ROUTER

expo-env-info 2.0.12 environment info:
System:
OS: Windows 11 10.0.26100
Binaries:
Node: 24.14.1
npm: 11.12.1
IDEs:
Android Studio: AI-253.31033.145.2533.15113396
npmPackages:
expo: ~54.0.33 => 54.0.33
expo-router: ~6.0.23 => 6.0.23
expo-updates: ~29.0.16 => 29.0.16
react: 19.1.0 => 19.1.0
react-dom: 19.1.0 => 19.1.0
react-native: 0.81.5 => 0.81.5
react-native-web: ~0.21.0 => 0.21.2
Expo Workflow: bare (was managed; switched to bare as workaround, see below)

EAS CLI: 18.8.1 (win32-x64, node-v24.14.1)
EAS Build profile: production, distribution: internal, channel: production
eas.json: appVersionSource: remote
New Architecture: enabled (newArchEnabled: true)

Sentry.init()

Sentry.init({
dsn: 'https://...@...ingest.de.sentry.io/...',
enabled: !DEV,
environment: DEV ? 'development' : 'production',
sendDefaultPii: false,
enableLogs: false,
});

Steps to Reproduce

  1. Managed Expo SDK 54 project (no local android/ or ios/ folders).
  2. Run: npx @sentry/wizard@latest -i reactNative --saas --org --project
    • Wizard adds the @sentry/react-native/expo config plugin to app.json
    • Adds Sentry.init(...) to app/_layout.tsx
    • Switches metro.config.js to getSentryExpoConfig
  3. Set the auth token: eas-cli secret:create --scope project --name SENTRY_AUTH_TOKEN --value
  4. Run: eas build --profile production --platform android
    • No local prebuild — let EAS do its cloud prebuild.
  5. Wait for build, install APK on device, trigger any error or captureMessage from the running app.
  6. Open Sentry dashboard:
    • Issues page receives the event (good)
    • Releases page is empty
    • Stack traces are unsymbolicated (minified line numbers like at <anonymous>:1:148273)

Expected Result

EAS's cloud prebuild applies the @sentry/react-native/expo config plugin's native
modifications to the generated android/ project. The Sentry gradle hook for source
map upload runs during the build, source maps land in Sentry, the build's release
appears in the dashboard, and stack traces from APK errors are symbolicated.

Actual Result

EAS emits this warning during cloud prebuild:

[@sentry/react-native/expo] Sentry native configuration is missing from your prebuilt Android project.
Run npx expo prebuild --clean to apply the Sentry Expo Plugin changes.
Without this, source maps upload and native crash reporting may not work correctly.

Build completes successfully and the APK runs fine, but:

  • No source maps uploaded — Sentry "Releases" stays empty.
  • Stack traces from production APK errors arrive unsymbolicated.

What I observed in the build log:

  • SENTRY_AUTH_TOKEN=******** IS set in build env (project secret reaches the build) ✓
  • Task :app:copySentryJsonConfiguration runs ✓
  • Task :sentry-react-native-expo:preBuild runs (UP-TO-DATE) ✓
  • No Uploading source maps for release... log line appears anywhere ✗

Suspected interaction: EAS performs an "eager bundle" step before gradle runs
(phase: EAGER_BUNDLE → Writing bundle output to: /tmp/.../index.js). The Sentry
plugin's source-map-upload hook expects gradle to do the React Native bundling, but
with EAS's eager bundle in place, the gradle bundle task is effectively replaced —
the hook never sees a bundle to upload source maps for.

Affected build IDs (account jetiex, project cleaning-tracker-2026):

  • b39590cb-ddd8-4ebd-83d9-cd63df30b620 (build 18)
  • 8790c7ca-7e8e-469f-a324-09ef8ee183ee (build 21)

Workaround that fixes it (verified working):

  1. Run npx expo prebuild --clean locally → plugin's native changes ARE applied
    correctly (gradle file gets Sentry wiring, android/sentry.properties generated).
  2. Add a .easignore mirroring .gitignore but allowing /android and /ios,
    so EAS uploads the locally-prebuilt native folders.
  3. Change runtimeVersion: { policy: "appVersion" } to a literal string in app.json
    — bare workflow rejects the policy form once /android ships.
  4. Add EAS lifecycle hook scripts to package.json calling the bundled
    sentry-eas-build-* binaries:
    "eas-build-on-success": "sentry-eas-build-on-success",
    "eas-build-on-error": "sentry-eas-build-on-error",
    "eas-build-on-complete": "sentry-eas-build-on-complete"
    These run after EAS's eager bundle and handle source map upload, filling the
    gap left by the bypassed gradle hook.
  5. Re-run eas build → no warning, source maps upload, release appears in Sentry,
    stack traces symbolicated.

Happy to provide a minimal reproducer if useful — let me know.

Metadata

Metadata

Assignees

No fields configured for issues without a type.

Projects

Status

No status

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions