What React Native libraries do you use?
Expo (mobile only), RN New Architecture, Hermes
Are you using sentry.io or on-premise?
sentry.io (SaS)
Are you using any other error monitoring solution alongside Sentry?
No
@sentry/react-native SDK Version
8.24.0 (the relevant file is unchanged on main as of 8.26.0)
How does your development environment look like?
React Native 0.86.3, Expo SDK 57, Android Gradle Plugin 8.12.0 (from React Native's gradle/libs.versions.toml), newArchEnabled=true, hermesEnabled=true.
Host root build.gradle pins rootProject.ext.ndkVersion = "27.1.12297006" (the React Native 0.86 catalog value) ahead of `apply plugin: "expo-root-project"`.
Android SDK on CI: ubuntu GitHub-hosted runner, only NDK 27.1.12297006 installed by our bootstrap before Gradle runs.
Sentry.init()
Sentry.init({
dsn: 'https://...@sentry.io/...',
// Nothing here matters for this report: it is a Gradle configuration
// issue in packages/core/android/build.gradle, independent of runtime options.
});
Steps to Reproduce
-
In a React Native 0.86 / Expo 57 app with the New Architecture enabled, pin the NDK in the root android/build.gradle (the React Native template form or Expo's expo-root-project plugin both end up with rootProject.ext.ndkVersion):
ext {
ndkVersion = "27.1.12297006"
}
-
Make sure only that NDK is installed under $ANDROID_HOME/ndk.
-
Run any Gradle evaluation, for example ./gradlew :app:help.
Expected Result
Every native module compiles with the host's pinned NDK. packages/core/android/build.gradle already reads compileSdkVersion, minSdkVersion, and targetSdkVersion from the host's rootProject.ext through safeExtGet, so I expected it to read ndkVersion the same way when the host sets one. react-native-screens, react-native-gesture-handler, react-native-svg, @stripe/stripe-react-native, react-native-reanimated, and Expo modules all do.
Actual Result
The build script never reads ndkVersion. With the New Architecture enabled the module has native code (externalNativeBuild { cmake { … } } and prefab true for ReactAndroid::reactnative), so AGP resolves an NDK for it and, since none is set, falls back to its own default and installs it during configuration. For AGP 8.12 that default is 27.0.12077973:
Checking the license for package NDK (Side by side) 27.0.12077973 in /usr/local/lib/android/sdk/licenses
Preparing "Install NDK (Side by side) 27.0.12077973 v.27.0.12077973".
Installing NDK (Side by side) 27.0.12077973 in /usr/local/lib/android/sdk/ndk/27.0.12077973
Effects: roughly a gigabyte downloaded per clean CI run on top of the pinned NDK, a configuration failure on offline or read-only SDK installs, and libsentry-tm-perf-logger.so built with a different NDK than the rest of the app.
Confirmed by adding a Gradle init script that prints each Android project's resolved ndkVersion after projectsEvaluated: with a stock root build.gradle, :sentry_react-native is the only project reporting null while every other one reports 27.1.12297006.
Proposed fix, keeping AGP's default when the host sets nothing:
android {
compileSdkVersion safeExtGet('compileSdkVersion', 31)
def hostNdkVersion = safeExtGet('ndkVersion', null)
if (hostNdkVersion != null) {
ndkVersion hostNdkVersion
}
// …
}
Workaround we ship in the host root build.gradle meanwhile:
subprojects { subproject ->
subproject.plugins.withId("com.android.library") {
subproject.android.ndkVersion = rootProject.ext.ndkVersion
}
}
Happy to open a PR with the one-line fix if that is easier.
What React Native libraries do you use?
Expo (mobile only), RN New Architecture, Hermes
Are you using sentry.io or on-premise?
sentry.io (SaS)
Are you using any other error monitoring solution alongside Sentry?
No
@sentry/react-native SDK Version
8.24.0 (the relevant file is unchanged on
mainas of 8.26.0)How does your development environment look like?
Sentry.init()
Steps to Reproduce
In a React Native 0.86 / Expo 57 app with the New Architecture enabled, pin the NDK in the root
android/build.gradle(the React Native template form or Expo'sexpo-root-projectplugin both end up withrootProject.ext.ndkVersion):ext { ndkVersion = "27.1.12297006" }Make sure only that NDK is installed under
$ANDROID_HOME/ndk.Run any Gradle evaluation, for example
./gradlew :app:help.Expected Result
Every native module compiles with the host's pinned NDK.
packages/core/android/build.gradlealready readscompileSdkVersion,minSdkVersion, andtargetSdkVersionfrom the host'srootProject.extthroughsafeExtGet, so I expected it to readndkVersionthe same way when the host sets one.react-native-screens,react-native-gesture-handler,react-native-svg,@stripe/stripe-react-native,react-native-reanimated, and Expo modules all do.Actual Result
The build script never reads
ndkVersion. With the New Architecture enabled the module has native code (externalNativeBuild { cmake { … } }andprefab trueforReactAndroid::reactnative), so AGP resolves an NDK for it and, since none is set, falls back to its own default and installs it during configuration. For AGP 8.12 that default is27.0.12077973:Effects: roughly a gigabyte downloaded per clean CI run on top of the pinned NDK, a configuration failure on offline or read-only SDK installs, and
libsentry-tm-perf-logger.sobuilt with a different NDK than the rest of the app.Confirmed by adding a Gradle init script that prints each Android project's resolved
ndkVersionafterprojectsEvaluated: with a stock rootbuild.gradle,:sentry_react-nativeis the only project reportingnullwhile every other one reports27.1.12297006.Proposed fix, keeping AGP's default when the host sets nothing:
android { compileSdkVersion safeExtGet('compileSdkVersion', 31) def hostNdkVersion = safeExtGet('ndkVersion', null) if (hostNdkVersion != null) { ndkVersion hostNdkVersion } // … }Workaround we ship in the host root
build.gradlemeanwhile:subprojects { subproject -> subproject.plugins.withId("com.android.library") { subproject.android.ndkVersion = rootProject.ext.ndkVersion } }Happy to open a PR with the one-line fix if that is easier.