{"record":{"id":"6fb3a5fda40c0ed7","repo":"dotnet/maui","slug":"navigationpage-must-have-a-root-page-before-being","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/Compatibility/Core/src/GTK/Renderers/NavigationPageRenderer.cs","lineNumber":222,"sourceCode":"\t\t\telse if (e.PropertyName == NavigationPage.BarTextColorProperty.PropertyName)\n\t\t\t\tUpdateBarTextColor();\n\t\t\telse if (e.PropertyName == VisualElement.BackgroundColorProperty.PropertyName)\n\t\t\t\tUpdateBackgroundColor();\n\t\t\telse if (e.PropertyName ==\n\t\t\t\tPlatformConfiguration.GTKSpecific.NavigationPage.BackButtonIconProperty.PropertyName)\n\t\t\t\tUpdateBackButtonIcon();\n\t\t\telse if (e.PropertyName == NavigationPage.CurrentPageProperty.PropertyName)\n\t\t\t\tUpdateCurrentPage();\n\t\t\telse if (e.PropertyName == NavigationPage.HasNavigationBarProperty.PropertyName)\n\t\t\t\tUpdateToolBar();\n\t\t}\n\n\t\tprivate void Init()\n\t\t{\n\t\t\tConfigurePageRenderer();\n\n\t\t\tif (Page.CurrentPage == null)\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\n\t\t\t_toolbarTracker.Navigation = Page;\n\t\t\t_currentPage = Page.CurrentPage;\n\t\t\tUpdateCurrentPage();\n\n\t\t\tNavigationController.PushRequested += OnPushRequested;\n\t\t\tNavigationController.PopRequested += OnPopRequested;\n\t\t\tNavigationController.PopToRootRequested += OnPopToRootRequested;\n\t\t\tNavigationController.RemovePageRequested += OnRemovedPageRequested;\n\t\t\tNavigationController.InsertPageBeforeRequested += OnInsertPageBeforeRequested;\n\n\t\t\tUpdateBarBackgroundColor();\n\t\t\tUpdateBarTextColor();\n\n\t\t\tNavigationController.Pages.ForEach(async p => await PushPageAsync(p, false));\n\n\t\t\tUpdateBackgroundColor();","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/dotnet/maui/blob/f377ff1c5ee04d334d8a925f50c83a6b7afddf03/src/Compatibility/Core/src/GTK/Renderers/NavigationPageRenderer.cs#L204-L240","documentation":"NavigationPageRenderer.Init requires NavigationPage.CurrentPage to be non-null before wiring up navigation events. CurrentPage is null when the NavigationPage was constructed without a root page and nothing has been pushed yet (the parameterless NavigationPage() ctor leaves it null). The renderer cannot function without a page to display, so it throws rather than rendering an empty shell.","triggerScenarios":"Creating new NavigationPage() (no root) and then setting it as MainPage or otherwise rendering it before a PushAsync. Concretely: NavigationPage.CurrentPage == null at the time the GTK renderer initializes.","commonSituations":"Using the parameterless NavigationPage() constructor intending to push pages later, but the page is rendered immediately. Refactoring that moves the root-page push after MainPage assignment. Migrating from a backend that tolerated an empty NavigationPage transiently.","solutions":["Pass a root page to the constructor: var nav = new NavigationPage(new ContentPage()); MainPage = nav;","If using the parameterless ctor, call Navigation.PushAsync(rootPage) before the page is rendered (before assigning to MainPage).","Ensure any custom NavigationPage subclass always sets a root before it becomes visible."],"exampleFix":"// before\nvar nav = new NavigationPage();\nMainPage = nav; // throws in renderer: CurrentPage null\n\n// after\nvar nav = new NavigationPage(new HomePage());\nMainPage = nav;","handlingStrategy":"validation","validationCode":"var nav = new NavigationPage();\nif (nav.CurrentPage == null)\n    nav.PushAsync(new ContentPage()); // or construct with a root\nMainPage = nav;","typeGuard":"static bool HasRoot(NavigationPage np) => np.CurrentPage != null;","tryCatchPattern":null,"preventionTips":["Prefer the NavigationPage(Page root) constructor.","Never assign a parameterless NavigationPage to MainPage without pushing first.","Unit-test that MainPage is a NavigationPage with a non-null CurrentPage."],"tags":["gtk","navigationpage","renderer","lifecycle","maui","xamarin"],"backgroundTag":null,"analyzedSha":"f377ff1c5ee04d334d8a925f50c83a6b7afddf03","analyzedAt":"2026-08-13T14:26:18.069Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}