dotnet/maui · error · NotSupportedException

Popped page does not appear on top of current navigation sta

Error message

Popped page does not appear on top of current navigation stack, please file a bug.

What it means

Thrown inside OnPopViewAsync on the iOS NavigationPage renderer when the page being popped does not match the Child of the current TopViewController (a ParentingViewController). This is an internal invariant check — the message explicitly says 'please file a bug' — indicating the renderer's internal navigation stack and the platform UINavigationController stack have diverged. It means the page the framework asked to pop is not what the renderer considers the topmost page.

Source

Thrown at src/Controls/src/Core/Compatibility/Handlers/NavigationPage/iOS/NavigationRenderer.cs:368

			}

			UpdateToolBarVisible();
			UpdateFlyoutMenuButton();
			return success;
		}

		protected virtual async Task<bool> OnPopViewAsync(Page page, bool animated)
		{
			if (_ignorePopCall)
				return true;

			_ = page.ToPlatform(MauiContext);
			var renderer = (IPlatformViewHandler)page.Handler;
			if (renderer == null || renderer.ViewController == null)
				return false;

			if (page != ((ParentingViewController)TopViewController).Child)
				throw new NotSupportedException("Popped page does not appear on top of current navigation stack, please file a bug.");

			var task = GetAppearedOrDisappearedTask(page);

			UIViewController poppedViewController;
			_ignorePopCall = true;
			poppedViewController = base.PopViewController(animated);

			var actuallyRemoved = poppedViewController == null ? true : !await task;
			_ignorePopCall = false;

			if (poppedViewController is ParentingViewController pvc)
				pvc.Disconnect(false);
			else
				poppedViewController?.Dispose();

			UpdateToolBarVisible();
			UpdateFlyoutMenuButton();
			return actuallyRemoved;

View on GitHub (pinned to f377ff1c5e)

Solutions

  1. Ensure no overlapping navigation calls — guard against re-entrancy by tracking in-flight navigation (e.g., disable back button or use a semaphore during navigation).
  2. If using RemovePage/InsertPageBefore, call them when no animation is in progress (pass animated:false or await completion of prior navigation).
  3. Avoid calling PopAsync in rapid succession from UI events without debouncing or a navigation lock.
  4. If the issue occurs after suspend/resume, verify the page stack is consistent in OnResume and rebuild it if necessary.
  5. File a bug if the stack divergence happens under normal, non-reentrant navigation — include a minimal reproduction.

Example fix

// before
private async void OnBackTapped(object sender, EventArgs e)
{
    await Navigation.PopAsync(); // re-entrant if tapped twice fast
}

// after
private bool _isNavigating;
private async void OnBackTapped(object sender, EventArgs e)
{
    if (_isNavigating) return;
    _isNavigating = true;
    try { await Navigation.PopAsync(); }
    finally { _isNavigating = false; }
}
Defensive patterns

Strategy: validation

Validate before calling

// Guard against re-entrant navigation
private static bool _isNavigating;
async Task SafePopAsync()
{
    if (_isNavigating) return;
    _isNavigating = true;
    try { await Navigation.PopAsync(); }
    finally { _isNavigating = false; }
}

Try / catch

try { await Navigation.PopAsync(animated: false); }
catch (NotSupportedException ex) when (ex.Message.Contains("Popped page does not appear"))
{
    // Stack desynchronized — force-refresh the navigation stack
    // Log and recover by rebuilding the stack

Prevention

When it happens

Trigger: The check is `if (page != ((ParentingViewController)TopViewController).Child)`. Triggered when: (1) a programmatic PopAsync is called while a previous navigation animation is still in-flight and the stacks have desynchronized; (2) InsertPageBefore or RemovePage mutates the logical stack without the platform stack following; (3) custom navigation overrides or third-party navigation libraries interfere with the standard push/pop flow; (4) race conditions between rapid PushAsync/PopAsync calls.

Common situations: 1) Double-tapping the back button rapidly causing overlapping pop operations. 2) Calling PopAsync from an event handler that fires during another navigation animation. 3) Using NavigationPage.RemovePage or InsertPageBefore during an active transition. 4) Custom renderers that manipulate the UIViewController stack directly. 5) Known edge cases after app sleep/resume where the platform view controller hierarchy was rebuilt inconsistently.

Related errors


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