accompanist: [Navigation Material] IllegalStateException: You cannot access the NavBackStackEntry's ViewModels after the NavBackStackEntry is destroyed.
Description Since moving to Compose 1.4.0-alpha04 + Accompanist 0.29.0-alpha, I’ve been seeing a lot of exceptions when opening a bottom sheet navigation target.
I’m still using Navigation Compose 2.5.3 at the moment, but I’ve just bumped up to 2.6.0-alpha04. I doubt it will make a difference, but I’ll report back.
Total guess on my part, but at first glance this looks like a race condition, where the back stack entry has been destroyed but Navigation Material is still using it. Might be due to the LaunchedEffect and Flow in SheetContentHost()? The backStack val in BottomSheetNavigator also looks suspicious. Adding some check on the backStack.lifecycle might be enough here.
Steps to reproduce I don’t actually have a way to reproduce this. Mostly seeing the crashes in Crashlytics.
Stack trace This stack trace is from a release build with R8 class merging enabled (i.e. it may look a bit weird).
Fatal Exception: java.lang.IllegalStateException: You cannot access the NavBackStackEntry's ViewModels after the NavBackStackEntry is destroyed.
at androidx.navigation.NavBackStackEntry.getViewModelStore(NavBackStackEntry.kt:202)
at androidx.lifecycle.viewmodel.compose.ViewModelKt.get(ViewModelKt.java:206)
at androidx.lifecycle.viewmodel.compose.ViewModelKt.get$default(ViewModelKt.java:195)
at androidx.lifecycle.viewmodel.compose.ViewModelKt.viewModel(ViewModelKt.java:120)
at app.tivi.episodedetails.EpisodeDetailsKt.EpisodeDetails(EpisodeDetailsKt.java:651)
at app.tivi.AppNavigationKt$addEpisodeDetails$2.invoke(AppNavigationKt.java:336)
at app.tivi.AppNavigationKt$addEpisodeDetails$2.invoke(AppNavigationKt.java:333)
at androidx.compose.ui.graphics.vector.VectorPainterKt$rememberVectorPainter$3.invoke$bridge(VectorPainter.kt:189)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:135)
at androidx.compose.runtime.internal.ComposableLambdaImpl$invoke$2.invoke(ComposableLambdaImpl.java:141)
at androidx.compose.foundation.ClickableKt$PressedInteractionSourceDisposableEffect$2.invoke$bridge(Clickable.kt:961)
at androidx.compose.runtime.internal.ComposableLambdaImpl$invoke$2.invoke(ComposableLambdaImpl.java:141)
at androidx.compose.foundation.ClickableKt$PressedInteractionSourceDisposableEffect$2.invoke$bridge(Clickable.kt:198)
at androidx.compose.runtime.RecomposeScopeImpl.compose(RecomposeScopeImpl.java:162)
at androidx.compose.runtime.ComposerImpl.recomposeToGroupEnd(Composer.kt:2435)
at androidx.compose.runtime.ComposerImpl.skipToGroupEnd(Composer.kt:2726)
at com.google.accompanist.navigation.material.BottomSheetNavigator$sheetContent$1.invoke(BottomSheetNavigator.java:237)
at app.tivi.home.upnext.UpNextKt$UpNextItem$1$1.invoke$bridge(UpNextKt.java:126)
at com.google.accompanist.navigation.material.BottomSheetNavigator$sheetContent$1.invoke(BottomSheetNavigator.java:185)
at androidx.compose.animation.AnimatedContentKt$AnimatedContent$7$1$1.invoke$bridge(AnimatedContent.kt:93)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:116)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.material.ModalBottomSheetKt$ModalBottomSheetLayout$1$6.invoke(ModalBottomSheetKt.java:730)
at androidx.compose.foundation.lazy.layout.LazySaveableStateHolderKt$LazySaveableStateHolderProvider$2.invoke$bridge(LazySaveableStateHolder.kt:588)
at androidx.compose.material.ModalBottomSheetKt$ModalBottomSheetLayout$1$6.invoke(ModalBottomSheetKt.java:553)
at androidx.compose.foundation.lazy.layout.LazySaveableStateHolderKt$LazySaveableStateHolderProvider$2.invoke$bridge(LazySaveableStateHolder.kt:41)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.material.SurfaceKt$Surface$1.invoke(Surface.kt:137)
at androidx.compose.material.SurfaceKt$Surface$1.invoke$bridge(Surface.kt:243)
at androidx.compose.material.SurfaceKt$Surface$1.invoke(Surface.kt:118)
at androidx.compose.material.SurfaceKt$Surface$1.invoke$bridge(Surface.kt:17)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocalKt.java:228)
at androidx.compose.material.SurfaceKt.Surface-F-jzlyU(SurfaceKt.java:115)
at androidx.compose.material.ModalBottomSheetKt$ModalBottomSheetLayout$1.invoke(ModalBottomSheet.kt:479)
at androidx.compose.material.ModalBottomSheetKt$ModalBottomSheetLayout$1.invoke(ModalBottomSheet.kt:456)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:116)
at androidx.compose.runtime.internal.ComposableLambdaImpl$invoke$1.invoke(ComposableLambdaImpl.java:127)
at androidx.compose.foundation.CanvasKt$Canvas$1.invoke$bridge(Canvas.kt:156)
at androidx.compose.runtime.internal.ComposableLambdaImpl$invoke$1.invoke(ComposableLambdaImpl.java:127)
at androidx.compose.foundation.CanvasKt$Canvas$1.invoke$bridge(Canvas.kt:126)
at androidx.compose.runtime.RecomposeScopeImpl.compose(RecomposeScopeImpl.java:162)
at androidx.compose.runtime.ComposerImpl.recomposeToGroupEnd(Composer.kt:2435)
at androidx.compose.runtime.ComposerImpl.skipCurrentGroup(ComposerImpl.java:2703)
at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(ComposerImpl.java:3326)
at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke$bridge(ComposerImpl.java:451)
at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(ComposerImpl.java:3304)
at androidx.compose.foundation.MagnifierKt$magnifier$4$sourceCenterInRoot$2$1.invoke$bridge(Magnifier.kt:157)
at androidx.compose.runtime.SnapshotStateKt__DerivedStateKt.observeDerivedStateRecalculations(SnapshotStateKt__DerivedStateKt.java:341)
at androidx.compose.runtime.SnapshotStateKt.observeDerivedStateRecalculations(SnapshotStateKt.java:1)
at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:3304)
at androidx.compose.runtime.ComposerImpl.recompose$runtime_release(Composer.kt:3269)
at androidx.compose.runtime.CompositionImpl.recompose(Composition.kt:771)
at androidx.compose.runtime.Recomposer.performRecompose(Recomposer.kt:1048)
at androidx.compose.runtime.Recomposer.access$performRecompose(Recomposer.kt:125)
at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.java:542)
at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.java:511)
at androidx.compose.foundation.layout.BoxKt$boxMeasurePolicy$1$measure$5.invoke$bridge(Box.kt:415)
at androidx.compose.ui.platform.AndroidUiFrameClock$withFrameNanos$2$callback$1.doFrame(AndroidUiFrameClock.android.kt:34)
at androidx.compose.ui.platform.AndroidUiDispatcher.performFrameDispatch(AndroidUiDispatcher.java:109)
at androidx.compose.ui.platform.AndroidUiDispatcher.access$performFrameDispatch(AndroidUiDispatcher.java:41)
at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.doFrame(AndroidUiDispatcher.android.kt:69)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1229)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1239)
at android.view.Choreographer.doCallbacks(Choreographer.java:899)
at android.view.Choreographer.doFrame(Choreographer.java:827)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1214)
at android.os.Handler.handleCallback(Handler.java:942)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7872)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
About this issue
- Original URL
- State: closed
- Created a year ago
- Reactions: 30
- Comments: 88
I can confirm it’s still an issue.
Chuck and I reworked the change so that it was eligible for cherry picking to 1.5. We are in a the process of getting that approved now. We know this is causing you a lot of issues so we are doing everything we can to get this fix to you ASAP.
The fix was released as part of 1.6.0-alpha01 today if you would like to give it a try but I understand it is hard to reproduce locally.
@bentrengrove Hello. I hope you are fine.
An update for navigation 2.7.1 has been released, which contains the fix you mentioned.
I have updated my demo example (https://github.com/Monabr/TestApp) and can summarize on 2 crashes.
I suggest you check it out for yourself on my updated demo example. Video and algorithm to reproduce is in the description of the repository. (https://github.com/Monabr/TestApp)
I can confirm the issue is still happening for me with version 0.32.0
I confirm what @ArturMytsko says. I’ve got the same issue on my application.
Yeah, still happens in 0.32
Thank you for all the effort reproducing these crashes. It is very appreciated. I’ll test out the updates and try to identify the root cause
Apologies, I just realised the fix is in Compose runtime not compiler. This unfortunately means it will be in Compose 1.6 and can’t be cherry picked back as it required an API change. The same release strategy for Accompanist will apply, once the fix is out we will do a release here that targets the new version of Compose.
Sorry I didn’t see the importance and scale of this issue sooner. I have notified the people internally who can help fix this and am working to find a solution.
I’m surprised you found that CL! No guarantees that lands, that was just me experimenting to understand the problem more.
This should be fixed as soon as possible! I see a huge number of crashes in my application and I don’t know how to fix it or get around it!
I’m still getting crash similar as the others from above. When dismissing the bottom sheet with a gesture, the app crashes with the NavBackStackEntry exception as well. Any updates on this?
I still have this issue when dismissing the bottom sheet. I’m using the latest dependencies. For more context I migrated from dialog route to bottom sheet one, the same code has no issues with dialog route.
Compose = 1.5.3 Navigation = 2.7.4 Accompanist = 0.32.0
I think the best thing we can do at this point is to put some pressure on their issue tracker so they realize this is actually a very crucial bug.
We are writing on this discussion while we know that it’s not a problem from accompanist, we should bother the big guys.
Seeing the same problem in some Prod APP. As we not use Navigation Animation it can’t be the cause.
I should also add, thank you @Monabr for the repo project. I have tested it and it reproduces the crash well
I don’t have existing in-use code, but strategically: preventing the
NavHostfrom recomposing was necessary.remember’ing theargumentkeys was what patched it for me. This is because inNavHost, it uses theNavGraphBuilder.() -> Unitlambda as arememberkey, and in debugging I saw that the lambda was changed during recompositions. This stops the lambda from being evaluated as changed.This was while I was able to reproduce the crash every time before the change. Perhaps this just glazed over a real, underlying issue, but it worked for the time.
An update: I recommend reading the comment in https://issuetracker.google.com/u/3/issues/254645321 about the status of this bug.
We will land the CL above which should improve this situation but not fully fix it, there will be another change coming that completes the fix. That fix is in the Compose compiler so we will have to wait for a stable compiler release that contains the fix. The process in that for accompanist will be once we have a stable release of the compiler we will do an Accompanist release that builds with that compiler. If by the time the compiler comes out we have both a stable 1.5 release and an alpha 1.6 release then we will make sure to cherry pick the compiler upgrade back to the stable release.
It looks like from the issue tracker that this hasn’t been marked as a bug, rather a feature request which sounds to me like something that won’t happen.
I can reproduce it consistently in my app by setting the animation duration scale to off in my emulator developer options and popping back on a specific screen (what makes this route different to others, I’m not quite sure).
Is there a workaround anyone has found? Reading the above, it doesn’t seem like it.
Might be a hint on how to reproduce: I can quite regularily reproduce this issue when changing the animationDurationScale to 0 within my phones developer settings (and also regularily see this issue on the pre-launch report on the google play store, where the devices have an animationDurationScale of 0 as well)
This also still applies on 0.30
Just FYI, encountered this crash after introducing ViewModel into the codebase. I’m using
compose-bom 2024.02.02,navigation-compose 2.7.7andlifecycle-runtime-ktx 2.7.0, without Accompanist. My app has bottom tabs with standalone NavHost and NavHostController per bottom tab (to implement mutli-backstack support).Not easily reproduceable, so can’t provide more info at this point.
Or, switch to compose-navigation-reimagined like me, and save your life.
Another fix for this has gone into the next version of androidx-navigation, seen here. I will close this bug for now because we are sure it is not an Accompanist bug. Once the next release of navigation is out, if you still experience this crash please do feel free to comment here and we can investigate.
Just an update, we are still trying to track down the source of this bug but one thing we think is it’s not an Accompanist bug but rather something between runtime and navigation. I will still leave this bug open for now until we have isolated it and have a new bug to link to.
Can you show us some code as how you did it? Thanks!
We saw this issue too. We use Hilt to inject the view models. Previously we had the view model provided by Hilt deeper down the composable hierarchy. It was done in a composable for our screen, which was wrapped in an ActionSheet with a scaffold with a top bar inside.
By moving it up to the navigation level and provide the Hilt injected viewModel to our screen on navigation, we managed to fix the crashes. Hope this can inspire others to do a workaround until it is finally fixed.
Having the same issue with nested NavHost and disabled animations Wen poping back stack with the nested NavHost - the app crashes with the same stacktrace
Is there are any workaround for this until it gets fixed from the library side?
I was able to reproduce the exception by using custom
rememberBottomSheetNavigatorfunction:This also reproduces the exception:
But if you use it like this it doesn’t crash anymore:
I hope this is helpful.
composeVersion = “1.4.2” accompanistVersion = “0.30.1” kotlinCompilerExtensionVersion = “1.4.6”
@D1maD1m0nd you could test this fix on my demo code. Just copy it to yourself and create custom NavHost with fix from link from bentrengrove.
@LittleTasteOfHeaven If possible, could you post that code somewhere to help us isolate the issue please?
Solution is to access viewmodel only in the right moment. This might require to adapt your components to have initial/loading state before viewmodel is available.
Providing a gist with an example here
Please provide feedback if it helped your case or not.
@jmhend A before and after snippet would be great if you could share?
This issue is still persistent in the latest stable and alpha releases.
@rmoustafa I understand. It would just be nice to have a demo code so that when there is a fix to check on it whether the problem remains or is no longer reproduced.
Could you write such a demo code that would also lead to an error?
Just create an empty project in android studio and reproduce the project structure which would lead to crash like I did in my post.
@bentrengrove Thanks for fixes. I updated to compose version 1.6.0-alpha01 and checked it on a test case, on which the bug was reproduced in Google issue. On it, this bug is no longer reproduced. However, after updating my application, I keep getting the same error. Do you have any thoughts on how this could be? Here is the stack trace:
Case 1: Hilt tried to get viewModel
Case 2: NavHost tried to
navController.setViewModelStore(viewModelStoreOwner.viewModelStore)My dependencies:
@bentrengrove Hello. Perhaps you can comment on something? Or at least notify the responsible persons? This problem is very critical, but here and on the Google tracker there is silence and no response from the developers. A lot of errors because of this problem!
@jossiwolf @jbw0033 Please comment on what this person said @radek606. This bug is a big problem.
If they don’t consider it a bug and provided some details on how things work, maybe you can mitigate this issue here and not wait for unlikely change from google?
Faced the same issue with
accompanist-navigation-materialandaccompanist-navigation-animation.I have the same issue when using
bottomSheetinnavigationwhen clicking the Scrim. Is there a workaround for now?I have same issue.
versions are
it occurs when app create nested NavHost for bottom navigation.
I have same issue with
accompanist-navigation-animationStack trace:Reproduce:
https://user-images.githubusercontent.com/53582576/216796059-07915088-7c9d-4882-94d7-dd72afc449e9.mp4
@jossiwolf I created private repository with code for reproduce, because it’s part of my private project. I invited you as collaborator for that repository https://github.com/AndreiRoze/IllegalStateExceptionBug
Thanks Chris! We’ll investigate when this could happen. Let us know if you find a repro in the meantime!
Cc @jbw0033