dotnet/maui · error · InvalidOperationException

PopToRootAsync is not supported globally on Android, please

Error message

PopToRootAsync is not supported globally on Android, please use a NavigationPage.

What it means

Thrown by the Platform class's explicit INavigation.PopToRootAsync(bool) implementation. On Android, popping to the root of the page stack is a NavigationPage operation; the global platform only handles modals. The guard routes developers to NavigationPage.

Source

Thrown at src/Compatibility/Core/src/Android/AppCompat/Platform.cs:182

					modalContainer.Dispose();
					source.TrySetResult(modal);
					CurrentPageController?.SendAppearing();
				}
			}

			UpdateAccessibilityImportance(CurrentPageController as Page, ImportantForAccessibility.Auto, true);

			return source.Task;
		}

		Task INavigation.PopToRootAsync()
		{
			return ((INavigation)this).PopToRootAsync(true);
		}

		Task INavigation.PopToRootAsync(bool animated)
		{
			throw new InvalidOperationException("PopToRootAsync is not supported globally on Android, please use a NavigationPage.");
		}

		Task INavigation.PushAsync(Page root)
		{
			return ((INavigation)this).PushAsync(root, true);
		}

		Task INavigation.PushAsync(Page root, bool animated)
		{
			throw new InvalidOperationException("PushAsync is not supported globally on Android, please use a NavigationPage.");
		}

		Task INavigation.PushModalAsync(Page modal)
		{
			return ((INavigation)this).PushModalAsync(modal, true);
		}

		async Task INavigation.PushModalAsync(Page modal, bool animated)

View on GitHub (pinned to f377ff1c5e)

Solutions

  1. Ensure the root is a NavigationPage so PopToRootAsync is handled by the NavigationPage renderer.
  2. Use modal pop (PopModalAsync) if the intent is to dismiss a modal, not to clear a page stack.
  3. Refactor navigation calls to obtain Navigation from the enclosing NavigationPage.

Example fix

// before
await page.Navigation.PopToRootAsync();

// after
if (NavigationPage.GetNavigationPage(page) is NavigationPage np)
    await np.Navigation.PopToRootAsync();
else
    await page.Navigation.PopModalAsync();
Defensive patterns

Strategy: validation

Validate before calling

// Only call PopToRootAsync when a NavigationPage hosts the page.
if (NavigationPage.GetNavigationPage(currentPage) is NavigationPage np)
    await np.Navigation.PopToRootAsync();
else
    await currentPage.Navigation.PopModalAsync();

Prevention

When it happens

Trigger: Calling await Application.Current.MainPage.Navigation.PopToRootAsync() on Android without a NavigationPage root. The platform INavigation is used instead of a NavigationPage's, triggering the throw.

Common situations: Cross-platform shared code calling PopToRootAsync unconditionally. App structured with a TabbedPage or single ContentPage root instead of a NavigationPage.

Related errors


AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13). Data as JSON: /api/errors/ce6bdbf1d9242ce6. Report an issue: GitHub.