PrismLibrary/Prism · error · NavigationException
NavigationException.RelativeNavigationRequiresNavigationPage
NavigationException.RelativeNavigationRequiresNavigationPage
Error message
NavigationException.RelativeNavigationRequiresNavigationPage
What it means
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.
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)
Example fix
// before
await _navigationService.NavigateAsync("../ViewB"); // currentPage not in a NavigationPage
// after
await _navigationService.GoBackAsync();
await _navigationService.NavigateAsync("ViewB"); Defensive patterns
Strategy: validation
Validate before calling
if (uri.Contains("../") && !MvvmHelpers.HasDirectNavigationPageParent(currentPage))
throw new InvalidOperationException("'../' requires a NavigationPage parent"); Try / catch
try { await nav.NavigateAsync(uri); }
catch (NavigationException ne) when (ne.Message == NavigationException.RelativeNavigationRequiresNavigationPage) { /* restructure nav */ } Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- NavigationException.NoPageIsRegistered
- The page type ' ' is not supported.
- Unable to determine the current page.
- The builder does not implement IRegistryAware
- NavigationException.NoPageIsRegistered
AI-assisted analysis of PrismLibrary/Prism@358118cd64 (2026-09-15).
Data as JSON: /api/errors/363e9f3c4baa26e8.
Report an issue: GitHub.
Appendix: source
Thrown at src/Maui/Prism.Maui/Navigation/PageNavigationService.cs:543
else if (currentPage is NavigationPage nav)
{
await ProcessNavigationForNavigationPage(nav, nextSegment, segments, parameters, useModalNavigation, pageAnimation);
}
else if (currentPage is TabbedPage tabbed)
{
await ProcessNavigationForTabbedPage(tabbed, nextSegment, segments, parameters, useModalNavigation, pageAnimation);
}
else if (currentPage is FlyoutPage flyout)
{
await ProcessNavigationForFlyoutPage(flyout, nextSegment, segments, parameters, useModalNavigation, pageAnimation);
}
}
protected virtual Task ProcessNavigationForRemovePageSegments(Page currentPage, string nextSegment, Queue<string> segments, INavigationParameters parameters, bool? useModalNavigation, bool? animated)
{
if (!MvvmHelpers.HasDirectNavigationPageParent(currentPage))
{
throw new NavigationException(NavigationException.RelativeNavigationRequiresNavigationPage, currentPage);
}
return CanRemoveAndPush(segments)
? RemoveAndPush(currentPage, nextSegment, segments, parameters, useModalNavigation, animated)
: RemoveAndGoBack(currentPage, nextSegment, segments, parameters, useModalNavigation, animated);
}
private static bool CanRemoveAndPush(Queue<string> segments)
{
return !segments.All(x => x == RemovePageSegment);
}
private Task RemoveAndGoBack(Page currentPage, string nextSegment, Queue<string> segments, INavigationParameters parameters, bool? useModalNavigation, bool? animated)
{
var pagesToRemove = new List<Page>();
var currentPageIndex = currentPage.Navigation.NavigationStack.Count;
if (currentPage.Navigation.NavigationStack.Count > 0)View on GitHub (pinned to 358118cd64)