dotnet/maui · error · InvalidOperationException

PushAsync is not supported globally on macOS, please use a N

Error message

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

What it means

The macOS global Platform has no non-modal page stack, so PushAsync has nowhere to push and PlatformNavigation throws InvalidOperationException. Pushing a page requires a NavigationPage whose renderer manages the stack. The global Platform only supports modal push/pop via its ModalPageTracker.

Source

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

		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()
		{
			return ((INavigation)this).PopModalAsync(true);
		}

		Task INavigation.PushModalAsync(Page modal, bool animated)
		{
			return _modalTracker.PushAsync(modal, _animateModals && animated);
		}

		Task<Page> INavigation.PopModalAsync(bool animated)

View on GitHub (pinned to f377ff1c5e)

Solutions

  1. Use a NavigationPage as MainPage: MainPage = new NavigationPage(root); then await page.Navigation.PushAsync(next).
  2. If the intent is modal, use await Navigation.PushModalAsync(page) which the global Platform supports.
  3. Gate PushAsync on macOS behind a check that a NavigationPage ancestor exists.

Example fix

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

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

Strategy: validation

Validate before calling

if (Application.Current.MainPage is NavigationPage)
    await page.Navigation.PushAsync(next);
else
    await page.Navigation.PushModalAsync(next);

Type guard

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

Prevention

When it happens

Trigger: Calling await Navigation.PushAsync(page) where Navigation resolves to the global macOS Platform: the calling Page's parent is the Application root (MainPage is not a NavigationPage).

Common situations: Shared code that calls Navigation.PushAsync on every platform. App structured with a single root ContentPage on macOS. Migrating navigation logic from iOS/Android.

Related errors


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