dotnet/maui · error · InvalidOperationException

PopAsync is not supported globally on GTK, please use a Navi

Error message

PopAsync is not supported globally on GTK, please use a NavigationPage.

What it means

The GTK Platform's explicit INavigation implementation does NOT support PopAsync at the global (application) navigation level — there is no global page stack to pop. PopAsync() delegates to PopAsync(true), which throws InvalidOperationException directing the developer to use a NavigationPage. (Modal pop is supported separately.)

Source

Thrown at src/Compatibility/Core/src/GTK/Platform.cs:162

		private void HandleChildRemoved(object sender, ElementEventArgs e)
		{
			var view = e.Element;
			DisposeModelAndChildrenRenderers(view);
		}

		void INavigation.InsertPageBefore(Page page, Page before)
		{
			throw new InvalidOperationException("InsertPageBefore is not supported globally on GTK, please use a NavigationPage.");
		}

		Task<Page> INavigation.PopAsync()
		{
			return ((INavigation)this).PopAsync(true);
		}

		Task<Page> INavigation.PopAsync(bool animated)
		{
			throw new InvalidOperationException("PopAsync is not supported globally on GTK, please use a NavigationPage.");
		}

		Task<Page> INavigation.PopModalAsync()
		{
			return ((INavigation)this).PopModalAsync(true);
		}

		Task<Page> INavigation.PopModalAsync(bool animated)
		{
			var modal = _modals.Last();
			_modals.Remove(modal);
			modal.DescendantRemoved -= HandleChildRemoved;

			var modalPage = GetRenderer(modal) as Container;

			var pageControl = PlatformRenderer.Child as IPageControl;

			Device.BeginInvokeOnMainThread(() =>

View on GitHub (pinned to f377ff1c5e)

Solutions

  1. Host pages inside a NavigationPage and pop via the NavigationPage's own navigation stack (NavigationPage.PopAsync).
  2. Use PopModalAsync for modal flows, which GTK does support globally.
  3. Branch navigation logic per-platform or ensure a NavigationPage root on GTK.

Example fix

// before — global pop (throws on GTK)
await Application.Current.MainPage.Navigation.PopAsync();
// after — root is a NavigationPage
Application.Current.MainPage = new NavigationPage(rootPage);
await Application.Current.MainPage.Navigation.PopAsync();
Defensive patterns

Strategy: validation

Validate before calling

static async Task SafePopAsync()
{
    if (Application.Current?.MainPage is NavigationPage nav)
        await nav.Navigation.PopAsync();
    else
        throw new InvalidOperationException("PopAsync on GTK requires a NavigationPage root.");
}

Type guard

static bool CanPopGloballyOnGtk => Application.Current?.MainPage is NavigationPage nav && nav.Navigation.NavigationStack.Count > 1;

Prevention

When it happens

Trigger: Calling Navigation.PopAsync() (or PopAsync(animated)) on the application-level navigation object when the root page is not a NavigationPage.

Common situations: Shared cross-platform code that calls Application.Current.MainPage.Navigation.PopAsync() — works on iOS/Android but not on GTK without a NavigationPage; default templates assuming global stack semantics.

Related errors


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