Skip to content

Android crash on NavView unmount: "Cannot remove Fragment attached to a different FragmentManager" in NavViewManager.onDropViewInstance #624

Description

@christian-apollo

Description of the bug

On Android, unmounting a NavigationView / MapView can crash the app with:

Fatal Exception: java.lang.IllegalStateException: Cannot remove Fragment attached to a different FragmentManager. Fragment N{50c0f7b} (afce94e3-0baa-45fa-839e-945c60a9c7ae id=0x726 tag=1830) is already attached to a FragmentManager.
       at androidx.fragment.app.BackStackRecord.remove(BackStackRecord.java:204)
       at com.google.android.react.navsdk.NavViewManager.onDropViewInstance(NavViewManager.java:317)
       at com.google.android.react.navsdk.NavViewManager.onDropViewInstance(NavViewManager.java:46)
       at com.facebook.react.fabric.mounting.SurfaceMountingManager.onViewStateDeleted(SurfaceMountingManager.java:1163)
       at com.facebook.react.fabric.mounting.SurfaceMountingManager.deleteView(SurfaceMountingManager.java:1202)
       at com.facebook.react.fabric.mounting.mountitems.IntBufferBatchMountItem.execute(IntBufferBatchMountItem.kt:118)
       at com.facebook.react.fabric.mounting.MountItemDispatcher.executeOrEnqueue(MountItemDispatcher.kt:340)
       at com.facebook.react.fabric.mounting.MountItemDispatcher.dispatchMountItems(MountItemDispatcher.kt:246)

Root cause: NavViewManager.onDropViewInstance removes the map fragment through reactContext.getCurrentActivity().getSupportFragmentManager():

https://github.com/googlemaps/react-native-navigation-sdk/blob/main/android/src/main/java/com/google/android/react/navsdk/NavViewManager.java#L307-L320

The fragment, however, was attached to whichever Activity was current when commitFragmentTransaction ran. If getCurrentActivity() returns a different Activity at drop time — e.g. the Activity was recreated (configuration change, background kill/restore) while the old one is still alive — the new Activity's FragmentManager never hosted this fragment, and BackStackRecord.remove throws.

androidx.fragment.app.BackStackRecord.remove throws exactly when fragment.mFragmentManager != null && fragment.mFragmentManager != mManager, which is precisely this mismatch. The same anti-pattern caused identical crashes in other RN libraries (e.g. stripe/stripe-react-native#1053).

Suggested fix: perform the remove transaction on the fragment's own getParentFragmentManager() (which is by definition the manager it is attached to) instead of the current Activity's, and guard commitNowAllowingStateLoss against an already-destroyed FragmentManager. This also allows cleanup to run when getCurrentActivity() is null, which currently leaks the fragmentMap entry. PR to follow.

iOS Platform

Not applicable (Android only)

Android Platform

Android 15/16 observed in the field (crash is OS-version independent)

React Native version

0.83.9 (new architecture / Fabric)

React version

19.2.7

Package version

0.16.3 (bug still present on main)

Steps to reproduce

  1. Render a NavigationView (or MapView) in an app using the new architecture.
  2. Cause the hosting Activity to be recreated while the fragment's original Activity is still registered as attached (e.g. configuration change / Activity recreation) so reactContext.getCurrentActivity() changes.
  3. Unmount the view (navigate away / conditional render toggles off).
  4. Fabric dispatches deleteViewonDropViewInstance → crash.

The race is timing-dependent, so it doesn't reproduce on every attempt, but it shows up consistently in production crash reporting (Crashlytics).

Expected vs Actual Behavior

Expected: the view unmounts and the fragment is detached cleanly.

Actual: fatal IllegalStateException: Cannot remove Fragment attached to a different FragmentManager, crashing the app.

Code Sample

{showMap && (
  <NavigationView
    androidStylingOptions={...}
    onMapViewControllerCreated={...}
    onNavigationViewControllerCreated={...}
  />
)}

Nothing app-specific is required — the crash is entirely inside NavViewManager.onDropViewInstance.

Additional Context

Full production stack trace attached above (app version 4.7.18290, com.apolloscooters). We are shipping the getParentFragmentManager() fix via patch-package in production and will link a PR with the same change.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions