dotnet/maui · error · InvalidOperationException
No Modal pages found in the stack, make sure you pushed a mo
Error message
No Modal pages found in the stack, make sure you pushed a modal page
What it means
ModalPageTracker.PopAsync takes the last modal from _modals; if the list is empty it throws InvalidOperationException. Pop on a modal stack that was never pushed means there is no modal to dismiss, so rather than returning null it fails fast. This guards the caller from a silent no-op that would break awaiting code.
Source
Thrown at src/Compatibility/Core/src/MacOS/ModalPageTracker.cs:38
_renderer.View.WantsLayer = true;
_modals = new List<Page>();
}
public List<Page> ModalStack => _modals;
public Task PushAsync(Page modal, bool animated)
{
_modals.Add(modal);
modal.DescendantRemoved += HandleChildRemoved;
Platform.NativeToolbarTracker.TryHide(modal as NavigationPage);
return PresentModalAsync(modal, animated);
}
public Task<Page> PopAsync(bool animated)
{
var modal = _modals.LastOrDefault();
if (modal == null)
throw new InvalidOperationException("No Modal pages found in the stack, make sure you pushed a modal page");
_modals.Remove(modal);
modal.DescendantRemoved -= HandleChildRemoved;
return HideModalAsync(modal, animated);
}
internal void LayoutSubviews()
{
if (_renderer == null || _renderer.View == null)
return;
foreach (var modal in _modals)
{
var modalRenderer = Platform.GetRenderer(modal);
if (modalRenderer != null)
modalRenderer.SetElementSize(new Size(_renderer.View.Bounds.Width, _renderer.View.Bounds.Height));
}
}
View on GitHub (pinned to f377ff1c5e)
Solutions
- Guard the call: if (Navigation.ModalStack.Count > 0) await Navigation.PopModalAsync();
- Track whether a modal was pushed before attempting to pop it.
- Ensure close handlers are not double-invoked (unsubscribe after first pop).
Example fix
// before
await Navigation.PopModalAsync(); // throws if stack empty
// after
if (Navigation.ModalStack.Count > 0)
await Navigation.PopModalAsync(); Defensive patterns
Strategy: validation
Validate before calling
if (Navigation.ModalStack.Count > 0)
await Navigation.PopModalAsync(); Type guard
static bool HasModal() => Navigation.ModalStack.Count > 0;
Prevention
- Always check ModalStack.Count before popping.
- Unsubscribe close handlers after a pop to avoid double-invocation.
- Centralize modal close logic in one place.
When it happens
Trigger: Calling Navigation.PopModalAsync() when no modal has been pushed on macOS (the modal stack is empty). Also reachable if a modal was already popped once and PopModalAsync is called again.
Common situations: Back/close handling that calls PopModalAsync unconditionally. Double-close where the modal is popped by both an event and explicit code. Shared code assuming a modal is on top without checking ModalStack.
Related errors
- PopAsync is not supported globally on macOS, please use a Na
- PopToRootAsync is not supported globally on macOS, please us
- PushAsync is not supported globally on macOS, please use a N
- RemovePage is not supported globally on macOS, please use a
- InsertPageBefore is not supported globally on macOS, please
AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13).
Data as JSON: /api/errors/f37d0b563a576ad7.
Report an issue: GitHub.