{"record":{"id":"06338539683762df","repo":"dotnet/maui","slug":"navigationpage-must-have-a-root-page-before-being-063385","errorCode":null,"errorMessage":"NavigationPage must have a root Page before being used. Either call PushAsync with a valid Page, or pass a Page to the constructor before usage.","messagePattern":"NavigationPage must have a root Page before being used\\. Either call PushAsync with a valid Page, or pass a Page to the constructor before usage\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Controls/src/Core/Compatibility/Handlers/NavigationPage/iOS/NavigationRenderer.cs","lineNumber":222,"sourceCode":"\t\t}\n\n\t\tpublic override void ViewDidLoad()\n\t\t{\n\t\t\tbase.ViewDidLoad();\n\n\t\t\tUpdateTranslucent();\n\n\t\t\t_secondaryToolbar = new SecondaryToolbar { Frame = new RectangleF(0, 0, 320, 44) };\n\t\t\tView.Add(_secondaryToolbar);\n\t\t\t_secondaryToolbar.Hidden = true;\n\n\t\t\tFindParentFlyoutPage();\n\n\t\t\tvar navPage = NavPage;\n\t\t\tINavigationPageController navPageController = NavPage;\n\t\t\tif (navPage.CurrentPage == null)\n\t\t\t{\n\t\t\t\tthrow new InvalidOperationException(\n\t\t\t\t\t\"NavigationPage must have a root Page before being used. Either call PushAsync with a valid Page, or pass a Page to the constructor before usage.\");\n\t\t\t}\n\n\t\t\tnavPageController.PushRequested += OnPushRequested;\n\t\t\tnavPageController.PopRequested += OnPopRequested;\n\t\t\tnavPageController.PopToRootRequested += OnPopToRootRequested;\n\t\t\tnavPageController.RemovePageRequested += OnRemovedPageRequested;\n\t\t\tnavPageController.InsertPageBeforeRequested += OnInsertPageBeforeRequested;\n\n\t\t\tUpdateBarBackground();\n\t\t\tUpdateBarTextColor();\n\t\t\tUpdateHideNavigationBarSeparator();\n\t\t\tUpdateUseLargeTitles();\n\n\t\t\tif (OperatingSystem.IsIOSVersionAtLeast(11))\n\t\t\t\tSetNeedsUpdateOfHomeIndicatorAutoHidden();\n\n\t\t\t// If there is already stuff on the stack we need to push it","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/dotnet/maui/blob/f377ff1c5ee04d334d8a925f50c83a6b7afddf03/src/Controls/src/Core/Compatibility/Handlers/NavigationPage/iOS/NavigationRenderer.cs#L204-L240","documentation":"This error is thrown by the iOS NavigationPage renderer during its initialization (OnElementChanged/setup). It checks NavPage.CurrentPage for null and throws InvalidOperationException if no root Page exists. A NavigationPage must have at least one Page on its stack before the platform renderer can build its UI — the renderer needs a concrete root view controller to push onto the UINavigationController.","triggerScenarios":"Occurs when a NavigationPage is constructed without a root page (e.g., `new NavigationPage()`) and then rendered on iOS without ever calling PushAsync. Also triggered if the NavigationPage's root page is removed or never set before the iOS renderer's ElementChanged fires. The check at line 222 is `if (navPage.CurrentPage == null)` inside the renderer setup that wires up PushRequested/PopRequested event handlers.","commonSituations":"1) Creating `new NavigationPage()` with no argument and then setting it as the MainPage or Application.MainPage before pushing content. 2) Migrating from Xamarin.Forms where the constructor sometimes lazily pushed a page, but the timing differs in MAUI's handler architecture. 3) NavigationPage created in XAML as a bare `<NavigationPage/>` without a child page element. 4) Dynamically replacing NavigationPage content where the old root is removed before the new one is set.","solutions":["Pass a root Page to the NavigationPage constructor: `new NavigationPage(new MyRootPage())` instead of a parameterless constructor.","If creating NavigationPage dynamically, call `PushAsync(rootPage)` synchronously immediately after construction, before it is rendered/displayed.","If using XAML, nest a child Page inside the NavigationPage element: `<NavigationPage> <ContentPage/> </NavigationPage>`.","Verify the root page is non-null and not removed during the renderer's initialization lifecycle."],"exampleFix":"// before\nvar navPage = new NavigationPage();\nMainPage = navPage;\nnavPage.PushAsync(new MyRootPage()); // too late — renderer already threw\n\n// after\nMainPage = new NavigationPage(new MyRootPage());","handlingStrategy":"validation","validationCode":"// Before assigning MainPage, verify the NavigationPage has a root page\nif (navPage.CurrentPage == null)\n    throw new InvalidOperationException(\"NavigationPage must have a root Page before use.\");\nMainPage = navPage;","typeGuard":"public static bool HasRootPage(NavigationPage navPage)\n    => navPage?.CurrentPage != null;","tryCatchPattern":null,"preventionTips":["Always construct NavigationPage with a root page: new NavigationPage(rootPage).","Add a startup assertion that MainPage (if NavigationPage) has CurrentPage != null.","Avoid parameterless NavigationPage() constructor."],"tags":["maui","ios","navigation","navigationpage","renderer"],"backgroundTag":null,"analyzedSha":"f377ff1c5ee04d334d8a925f50c83a6b7afddf03","analyzedAt":"2026-08-13T14:26:18.069Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}