dotnet/maui · error · InvalidOperationException

PopToRootAsync is not supported globally on macOS, please us

Error message

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

What it means

The macOS global Platform does not maintain a page navigation stack; PopToRootAsync is a stack operation with no stack to operate on, so PlatformNavigation throws InvalidOperationException. Root-to-root popping must be performed by a NavigationPage that owns the stack. Same family as the global Pop/Push/RemovePage/InsertPageBefore limitations on macOS.

Source

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

		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)
		{
			throw new InvalidOperationException("PushAsync is not supported globally on macOS, please use a NavigationPage.");
		}

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

		Task<Page> INavigation.PopModalAsync()

View on GitHub (pinned to f377ff1c5e)

Solutions

  1. Wrap the root in a NavigationPage and PopToRootAsync through it: MainPage = new NavigationPage(root); then await page.Navigation.PopToRootAsync();
  2. If only modals are used, switch to Navigation.PopModalAsync() (may need a loop to clear the modal stack).
  3. Guard the call to only run when NavigationPage is in the hierarchy on macOS.

Example fix

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

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

Strategy: validation

Validate before calling

if (page.Parent is NavigationPage)
    await page.Navigation.PopToRootAsync();

Type guard

static bool IsNavigationPageRoot(Page root) => root is NavigationPage;

Prevention

When it happens

Trigger: Calling await Navigation.PopToRootAsync() when Navigation points at the global macOS Platform — MainPage is not a NavigationPage, so no stack exists.

Common situations: Shared code calling PopToRootAsync across all backends. App with a bare root ContentPage on macOS. Reset-flow code (e.g. logout returning to root) assuming global stack support.

Related errors


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