{"record":{"id":"363e9f3c4baa26e8","repo":"PrismLibrary/Prism","slug":"navigationexception-relativenavigationrequiresnavigationpage","errorCode":"NavigationException.RelativeNavigationRequiresNavigationPage","errorMessage":"NavigationException.RelativeNavigationRequiresNavigationPage","messagePattern":"NavigationException\\.RelativeNavigationRequiresNavigationPage","errorType":"exception","errorClass":"NavigationException","httpStatus":null,"severity":"error","filePath":"src/Maui/Prism.Maui/Navigation/PageNavigationService.cs","lineNumber":543,"sourceCode":"        else if (currentPage is NavigationPage nav)\n        {\n            await ProcessNavigationForNavigationPage(nav, nextSegment, segments, parameters, useModalNavigation, pageAnimation);\n        }\n        else if (currentPage is TabbedPage tabbed)\n        {\n            await ProcessNavigationForTabbedPage(tabbed, nextSegment, segments, parameters, useModalNavigation, pageAnimation);\n        }\n        else if (currentPage is FlyoutPage flyout)\n        {\n            await ProcessNavigationForFlyoutPage(flyout, nextSegment, segments, parameters, useModalNavigation, pageAnimation);\n        }\n    }\n\n    protected virtual Task ProcessNavigationForRemovePageSegments(Page currentPage, string nextSegment, Queue<string> segments, INavigationParameters parameters, bool? useModalNavigation, bool? animated)\n    {\n        if (!MvvmHelpers.HasDirectNavigationPageParent(currentPage))\n        {\n            throw new NavigationException(NavigationException.RelativeNavigationRequiresNavigationPage, currentPage);\n        }\n\n        return CanRemoveAndPush(segments)\n            ? RemoveAndPush(currentPage, nextSegment, segments, parameters, useModalNavigation, animated)\n            : RemoveAndGoBack(currentPage, nextSegment, segments, parameters, useModalNavigation, animated);\n    }\n\n    private static bool CanRemoveAndPush(Queue<string> segments)\n    {\n        return !segments.All(x => x == RemovePageSegment);\n    }\n\n    private Task RemoveAndGoBack(Page currentPage, string nextSegment, Queue<string> segments, INavigationParameters parameters, bool? useModalNavigation, bool? animated)\n    {\n        var pagesToRemove = new List<Page>();\n\n        var currentPageIndex = currentPage.Navigation.NavigationStack.Count;\n        if (currentPage.Navigation.NavigationStack.Count > 0)","sourceCodeStart":525,"sourceCodeEnd":561,"githubUrl":"https://github.com/PrismLibrary/Prism/blob/358118cd640d9a22ff8cf21c8ad197fa038b7990/src/Maui/Prism.Maui/Navigation/PageNavigationService.cs#L525-L561","documentation":"Relative navigation segments like '../' (remove-page) require the current page to be hosted directly inside a NavigationPage, because 'remove' semantics manipulate the NavigationPage's stack. MvvmHelpers.HasDirectNavigationPageParent(currentPage) returned false, so Prism throws instead of silently mis-navigating.","triggerScenarios":"Executing a navigation URI containing '../' (ProcessNavigationForRemovePageSegments) where currentPage has no direct NavigationPage parent — e.g. it is a tab child of a TabbedPage, the app root, or was pushed modally.","commonSituations":"Using '../SomePage' inside a TabbedPage tab; navigating with remove-segments from a page displayed with useModalNavigation; moving apps from NavigationPage-based layouts to shell/tab layouts while keeping old back-rewrite URIs.","solutions":["Wrap the page's branch in a NavigationPage so relative '..' segments have a stack to manipulate","Remove the '../' segment and use GoBackAsync or an absolute/relative page path appropriate to the container","Restructure the URI to use navigation modes supported by the actual container (e.g. tab selection or modal navigation)"],"exampleFix":"// before\nawait _navigationService.NavigateAsync(\"../ViewB\"); // currentPage not in a NavigationPage\n// after\nawait _navigationService.GoBackAsync();\nawait _navigationService.NavigateAsync(\"ViewB\");","handlingStrategy":"validation","validationCode":"if (uri.Contains(\"../\") && !MvvmHelpers.HasDirectNavigationPageParent(currentPage))\n    throw new InvalidOperationException(\"'../' requires a NavigationPage parent\");","typeGuard":null,"tryCatchPattern":"try { await nav.NavigateAsync(uri); }\ncatch (NavigationException ne) when (ne.Message == NavigationException.RelativeNavigationRequiresNavigationPage) { /* restructure nav */ }","preventionTips":["Only use '../' remove-segments inside NavigationPage-hosted stacks","Prefer GoBackAsync/GoBackToRootAsync for modal or tab flows","Document container layout (tabs vs NavigationPage) with the team to avoid wrong back URIs"],"tags":["prism","maui","navigation","navigationpage"],"backgroundTag":"invalid-state-transition","analyzedSha":"358118cd640d9a22ff8cf21c8ad197fa038b7990","analyzedAt":"2026-09-15T15:00:31.079Z","contentChangedAt":"2026-09-15T15:00:31.079Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}