dotnet/maui · error · InvalidOperationException

PopAsync is not supported globally on macOS, please use a Na

Error message

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

What it means

The macOS global Platform (PlatformNavigation) implements INavigation but exposes only modal push/pop; the non-modal PopAsync is a stack operation it does not support, so it throws InvalidOperationException. Non-modal navigation on macOS must go through a NavigationPage whose renderer owns the stack. This is the macOS analogue of the GTK global-stack limitation.

Source

Thrown at src/Compatibility/Core/src/MacOS/PlatformNavigation.cs:40

		public IReadOnlyList<Page> ModalStack => _modalTracker.ModalStack;

		public IReadOnlyList<Page> NavigationStack => new List<Page>();

		public bool AnimateModalPages
		{
			get { return _animateModals; }
			set { _animateModals = value; }
		}

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

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

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

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

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

		Task INavigation.PushAsync(Page root, bool animated)

View on GitHub (pinned to f377ff1c5e)

Solutions

  1. Host the page in a NavigationPage: MainPage = new NavigationPage(root); then call PopAsync on a page within it.
  2. If using modals, call Navigation.PopModalAsync() instead, which the global Platform supports.
  3. Runtime-guard PopAsync so it only runs when a NavigationPage ancestor exists.

Example fix

// before
MainPage = new ContentPage();
await page.Navigation.PopAsync(); // throws on macOS

// after
MainPage = new NavigationPage(new ContentPage());
await page.Navigation.PopAsync();
Defensive patterns

Strategy: validation

Validate before calling

if (Application.Current.MainPage is NavigationPage)
    await page.Navigation.PopAsync();
else if (Navigation.ModalStack.Count > 0)
    await Navigation.PopModalAsync();

Type guard

static bool HasNavStack() => Application.Current?.MainPage is NavigationPage;

Prevention

When it happens

Trigger: Calling await Navigation.PopAsync() where Navigation resolves to the global macOS Platform — i.e. the Page's parent is the Application/Platform root, not a NavigationPage (MainPage is a bare page).

Common situations: Shared navigation code that assumes global Pop works on all backends. App with MainPage set to a ContentPage on macOS. Hardware/menu back handling calling PopAsync unconditionally.

Related errors


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