{"record":{"id":"f37d0b563a576ad7","repo":"dotnet/maui","slug":"no-modal-pages-found-in-the-stack-make-sure-you-p","errorCode":null,"errorMessage":"No Modal pages found in the stack, make sure you pushed a modal page","messagePattern":"No Modal pages found in the stack, make sure you pushed a modal page","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Compatibility/Core/src/MacOS/ModalPageTracker.cs","lineNumber":38,"sourceCode":"\t\t\t_renderer.View.WantsLayer = true;\n\t\t\t_modals = new List<Page>();\n\t\t}\n\n\t\tpublic List<Page> ModalStack => _modals;\n\n\t\tpublic Task PushAsync(Page modal, bool animated)\n\t\t{\n\t\t\t_modals.Add(modal);\n\t\t\tmodal.DescendantRemoved += HandleChildRemoved;\n\t\t\tPlatform.NativeToolbarTracker.TryHide(modal as NavigationPage);\n\t\t\treturn PresentModalAsync(modal, animated);\n\t\t}\n\n\t\tpublic Task<Page> PopAsync(bool animated)\n\t\t{\n\t\t\tvar modal = _modals.LastOrDefault();\n\t\t\tif (modal == null)\n\t\t\t\tthrow new InvalidOperationException(\"No Modal pages found in the stack, make sure you pushed a modal page\");\n\t\t\t_modals.Remove(modal);\n\t\t\tmodal.DescendantRemoved -= HandleChildRemoved;\n\t\t\treturn HideModalAsync(modal, animated);\n\t\t}\n\n\t\tinternal void LayoutSubviews()\n\t\t{\n\t\t\tif (_renderer == null || _renderer.View == null)\n\t\t\t\treturn;\n\n\t\t\tforeach (var modal in _modals)\n\t\t\t{\n\t\t\t\tvar modalRenderer = Platform.GetRenderer(modal);\n\t\t\t\tif (modalRenderer != null)\n\t\t\t\t\tmodalRenderer.SetElementSize(new Size(_renderer.View.Bounds.Width, _renderer.View.Bounds.Height));\n\t\t\t}\n\t\t}\n","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/dotnet/maui/blob/f377ff1c5ee04d334d8a925f50c83a6b7afddf03/src/Compatibility/Core/src/MacOS/ModalPageTracker.cs#L20-L56","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"// before\nawait Navigation.PopModalAsync(); // throws if stack empty\n\n// after\nif (Navigation.ModalStack.Count > 0)\n    await Navigation.PopModalAsync();","handlingStrategy":"validation","validationCode":"if (Navigation.ModalStack.Count > 0)\n    await Navigation.PopModalAsync();","typeGuard":"static bool HasModal() => Navigation.ModalStack.Count > 0;","tryCatchPattern":null,"preventionTips":["Always check ModalStack.Count before popping.","Unsubscribe close handlers after a pop to avoid double-invocation.","Centralize modal close logic in one place."],"tags":["macos","modal","navigation","validation","maui","xamarin"],"backgroundTag":null,"analyzedSha":"f377ff1c5ee04d334d8a925f50c83a6b7afddf03","analyzedAt":"2026-08-13T14:26:18.069Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}