Repository navigation
Android release builds crash on launch: react-native-shiki-engine resolves fbjni:+ to 0.8.1 #13710
Description
Activity
Triage
Confirmed. The report matches current
main(ed809f7ad2) and the nightly it names (4293433e, which is an ancestor ofmain). Nothing since that commit touches the mobile Android build orreact-native-shiki-engine. No other issue or pull request in this repo tracks it. Keep this open.A fresh Android resolve today links
libfbjni.sofrom fbjni 0.8.1 into an app whose C++ runtime is still React Native’s NDK 27.1libc++_shared.so. The process dies inReactNativeApplicationEntryPoint.loadReactNativebefore any JavaScript runs. Builds that already resolvedfbjni:+to 0.7.0 stay on that copy until the dynamic-version cache expires, which is why a warm Gradle cache does not reproduce it.What the report gets right
fbjni 0.8.0 and 0.8.1 were both published on 2026-09-25 (0.8.0 at 16:04 UTC, 0.8.1 at 17:36 UTC). Both POMs are on Maven Central. 0.8.0 is the NDK r28c rebuild, done so fbjni would be ready for facebook/react-native#58650. That pull request is still open. 0.8.1 only restores the Prefab package name from
fbjni-androidback tofbjni.+therefore selects 0.8.1, and that.sois the r28c binary.React Native 0.86.3 does not.
packages/react-native/gradle/libs.versions.tomlon tagv0.86.3setsfbjni = "0.7.0"andndkVersion = "27.1.12297006". The published Gradle module forcom.facebook.react:react-android:0.86.3requirescom.facebook.fbjni:fbjni:0.7.0on the release runtime variant. The React Native Gradle plugin forcesreact-androidandhermes-androidonly. It does not force fbjni, so the highest request wins.This app is that pair of versions, and the floating request is
react-native-shiki-engine@0.3.12:"react-native": "0.86.3", ... "react-native-shiki-engine": "^0.3.12",
android/build.gradlein that package, on tagv0.3.12and on the library’s currentmain, still hasimplementation "com.facebook.fbjni:fbjni:+". The lockfile is exactly 0.3.12. npm has no newer release. The library’s own skiniks/react-native-shiki-engine#273, filed by the same author, is still open.The other Android libraries checked do not make this request.
react-native-screens,react-native-gesture-handler,react-native-nitro-modules, andexpo-modules-coreexcludelibfbjni.sofrom their own AARs (gesture-handler also excludes the Maven group).expo-modules-coreonlycompileOnlys fbjni 0.5.1.react-native-nitro-markdown,react-native-keyboard-controller,react-native-svg,react-native-webview, and@react-native-menu/menudo not declare fbjni. None of the in-repo Android modules do either.The launch stack does not require the highlighter to run. Autolinking compiles the library in because it is a dependency. The JS import is dynamic and only used once a review diff is highlighted:
async function createNativeReviewDiffHighlighter(): Promise<NativeReviewDiffHighlighterHandle> { const nativeEngineModule = await import("react-native-shiki-engine"); if (!nativeEngineModule.isNativeEngineAvailable()) {
ReactNativeFeatureFlagsCxxInteroploadslibfbjni.sofromMainApplication.onCreate. The missing symbol is__cxa_init_primary_exception, which NDK r28’s libc++ references and NDK r27’slibc++_shared.sodoes not provide. That is the same break as facebook/react-native#54886.What to be careful with
Editing
android/build.gradleby hand does not survive this repo.apps/mobile/androidis generated and gitignored, and the Android scripts runexpo prebuild --clean:# generated native folders /ios /android
EAS builds prebuild from
app.config.tstoo. The force has to be applied from a config plugin, the same waywithAndroidGradleHeapis registered here:"./plugins/withAndroidCleartextTraffic.cjs", "./plugins/withAndroidGradleHeap.cjs",
gradle.propertiescannot express it. UsewithProjectBuildGradleand putresolutionStrategy.force 'com.facebook.fbjni:fbjni:0.7.0'onallprojects.configurations. 0.7.0 is the versionreact-android:0.86.3requires, not a permanent pin. When this app picks up the NDK r28c bump from react-native#58650, that force has to move with React Native’s fbjni or the mismatch flips the other way.This is not release-specific. Debug and release share the resolution. “Release” in the report is the build that resolved cleanly after 0.8.1 existed. An APK already built against 0.7.0 is fine. An Expo update cannot replace
libfbjni.so. The nightly named in the report stays broken until a new Android binary is built.Workaround
Until that plugin is in a build, a clean Android build needs the force injected into the generated root
android/build.gradleafter prebuild. A warm cache that still has+resolved to 0.7.0 will keep launching, and it will stop doing that within Gradle’s dynamic-version window (24 hours) or on the next--refresh-dependencies.Labels / next
- Type: bug, accepted.
- Labels:
bug,accepted. Leaveneeds-triage,via-triage, andupstreamoff. The library bug is Cannot dismiss the plan overlay after agent calls the planning tool #273; this app can ship the pin without waiting for it. - Next: add the config plugin above and register it beside
withAndroidGradleHeap. The pull request changes native bytes, so it should take the native-change label. A pnpm patch that rewrites shiki-engine’sfbjni:+to0.7.0is the narrower alternative and goes stale on the next library release that still uses+.
- addedbugSomething is broken or behaving incorrectly.Something is broken or behaving incorrectly.acceptedfeature request acceptedfeature request acceptedvia-triageFiled through npx t3 triageFiled through npx t3 triage
on Sep 25, 2026 - added a commit that references this issue
on Sep 26, 2026 I can confirm both the diagnosis and the fix on a Galaxy A55 (arm64-v8a, preview APK).
Problem
Same crash site as reported (
MainApplication.onCreate:43toDefaultNewArchitectureEntryPoint.loadtoReactNativeFeatureFlagsCxxInterop.<clinit>). On my device logcat shows it as a SoLoader lookup failure rather than theUnsatisfiedLinkErrorin the issue body, but same library and same call chain:E AndroidRuntime: com.facebook.soloader.SoLoaderDSONotFoundError: couldn't find DSO to load: libfbjni.so at com.facebook.soloader.SoLoader.doLoadLibraryBySoName(SoLoader.java:1216) ... at com.facebook.react.internal.featureflags.ReactNativeFeatureFlagsCxxInterop.<clinit>(ReactNativeFeatureFlagsCxxInterop.kt:28) at com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load(DefaultNewArchitectureEntryPoint.kt:101) at com.facebook.react.ReactNativeApplicationEntryPoint.loadReactNative(ReactNativeApplicationEntryPoint.java:31) at com.t3tools.t3code.preview.MainApplication.onCreate(MainApplication.kt:43)This is commit-independent: I bisected 126 commits and every build crashed identically, including a build differing from a known-good one by a single web-only file. Binary forensics back your fbjni theory:
libfbjni.soin my last working APK (built Sep 24) is clang 18 (NDK 27), in the crashing APK (built Sep 27) it is clang 19 (NDK 28).Fix
Your workaround holds: with
resolutionStrategy.force 'com.facebook.fbjni:fbjni:0.7.0'inandroid/build.gradle,dependencyInsightreportscom.facebook.fbjni:fbjni:0.7.0 (forced)andfbjni:+ -> 0.7.0, and the packagedlibfbjni.sois back to clang 18.Validation
gradlew :app:dependencyInsightshows 0.7.0 forced, no 0.8.1 in the graph.- Artifact check on the built APK:
libfbjni.soreports clang 18 again. - Installed the fixed build on the A55: the app opens normally, no more white screen crash.
Hi,
Where did y'all download preview APKs ?I have my agent build the apk for me every few days. I can send you my skill and script for it, though they are configured for my specific setup.
Oh okay, well I actually did the same thing but with CI (and also had AI fix this issue) : https://github.com/VibedByKaKi/t3-code-android-nightly
I was just hoping you somehow found some officially supported APKs
- added 2 commits that reference this issue
on Sep 27, 2026 kvnloo commented
on Sep 29, 2026 ContributorMore actionsI put the app-side guard in #13967: it forces
com.facebook.fbjni:fbjni:0.7.0through an Expo config plugin so clean prebuilds/EAS builds cannot float to 0.8.x again. Kept it narrow: no React Native upgrade and no unrelated Gradle changes.I’m leaving that PR draft until the native verification is complete (fresh dependency resolution, release APK launch, and artifact check), since this one fails before JS and the device/build proof matters more than CI-only coverage.
Fresh Android builds of the mobile app now exit immediately on launch. logcat:
react-native-shiki-engine@0.3.12declaresimplementation "com.facebook.fbjni:fbjni:+". fbjni 0.8.1 was published to Maven Central on 2026-09-25, so Gradle resolves the conflict with RN'sfbjni:0.7.0up to 0.8.1 (gradlew :app:dependencyInsight --dependency com.facebook.fbjni:fbjni). Thatlibfbjni.sois built with the NDK 28 toolchain (clang 19). RN 0.86 builds with NDK 27.1 and packages thatlibc++_shared.so, which lacks the symbol.Builds with fbjni 0.7.0 already in the Gradle cache may not reproduce this.
Workaround: force RN's version in
android/build.gradle:A permanent fix could apply this through the app's Expo config plugin, or pin the version in react-native-shiki-engine.
Seen on
v0.0.43-nightly.20260925.2269(4293433e), Pixel 11 Pro XL, arm64-v8a.