PrismLibrary/Prism · error · NavigationException

NavigationException.GoBackRequiresNavigationPage

NavigationException.GoBackRequiresNavigationPage

Error message

NavigationException.GoBackRequiresNavigationPage

What it means

GoBackToAsync searches the current NavigationStack (in reverse) for a page whose navigation name matches the requested viewName. If no page with that name exists in the stack, goBackPage is null and Prism throws NavigationException with GoBackRequiresNavigationPage — you cannot 'go back to' a page that was never pushed.

Solutions

  1. Verify the page was pushed with exactly the registered name (ViewModelLocator.GetNavigationName) and that it is still on page.Navigation.NavigationStack.
  2. Log/dump the current stack names (ViewModelLocator.GetNavigationName per page) before calling GoBackToAsync to confirm the target exists.
  3. Use GoBackToRootAsync or NavigateAsync with a relative URI instead when the target may not be on the stack.
  4. Fix the view name string to match the registration (e.g. "Views/MainPage" vs "MainPage").

Example fix

// before
await _navigationService.GoBackToAsync("MainPage");
// after
var stack = _pageAccessor.Page.Navigation.NavigationStack;
bool exists = stack.Any(p => ViewModelLocator.GetNavigationName(p) == "MainPage");
if (exists)
    await _navigationService.GoBackToAsync("MainPage");
else
    await _navigationService.NavigateAsync("MainPage");
Defensive patterns

Strategy: validation

Validate before calling

var stack = currentPage.Navigation.NavigationStack;
bool targetOnStack = stack.Any(p => ViewModelLocator.GetNavigationName(p) == viewName);
if (!targetOnStack) await _navigationService.NavigateAsync(viewName);

Type guard

bool IsOnStack(Page current, string viewName) =>
    current.Navigation.NavigationStack.Any(p => ViewModelLocator.GetNavigationName(p) == viewName);

Try / catch

try { await _navigationService.GoBackToAsync(viewName); }
catch (NavigationException ex) when (ex.Message.Contains(NavigationException.GoBackRequiresNavigationPage))
{ await _navigationService.NavigateAsync(viewName); }

Prevention

When it happens

Trigger: Calling GoBackToAsync("SomeView") when SomeView is not anywhere in the current INavigation NavigationStack (never pushed, already popped, or pushed with a different registered name).

Common situations: Typos or casing mismatches between the view name registered in Prism and the string passed to GoBackToAsync; assuming a page is on the stack when a previous GoBackToRootAsync/GoBackAsync already removed it; navigating to the target via Uri path syntax so it was created as part of a different name.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of PrismLibrary/Prism@358118cd64 (2026-09-15). Data as JSON: /api/errors/6603fab0d10f78bd. Report an issue: GitHub.

Appendix: source

Thrown at src/Maui/Prism.Maui/Navigation/PageNavigationService.cs:173

    {
        await WaitForPendingNavigationRequests();
        try
        {
            parameters ??= new NavigationParameters();

            parameters.GetNavigationParametersInternal().Add(KnownInternalParameters.NavigationMode, NavigationMode.Back);

            var page = GetCurrentPage();
            var canNavigate = await MvvmHelpers.CanNavigateAsync(page, parameters);
            if (!canNavigate)
            {
                throw new NavigationException(NavigationException.IConfirmNavigationReturnedFalse, page);
            }

            var pagesToDestroy = page.Navigation.NavigationStack.ToList(); // get all pages to destroy
            pagesToDestroy.Reverse(); // destroy them in reverse order
            var goBackPage = pagesToDestroy.FirstOrDefault(p => ViewModelLocator.GetNavigationName(p) == viewName) 
                ?? throw new NavigationException(NavigationException.GoBackRequiresNavigationPage); // find the go back page
            var index = pagesToDestroy.IndexOf(goBackPage);
            pagesToDestroy.RemoveRange(index, pagesToDestroy.Count - index); // don't destroy pages from the go back page to the root page
            var pagesToRemove = pagesToDestroy.Skip(1).ToList(); // exclude the current page from the destroy pages

            bool animated = !parameters.ContainsKey(KnownNavigationParameters.Animated) || parameters.GetValue<bool>(KnownNavigationParameters.Animated);
            NavigationSource = PageNavigationSource.NavigationService;
            foreach(var removePage in pagesToRemove)
            {
                page.Navigation.RemovePage(removePage);
            }
            await page.Navigation.PopAsync(animated);
            NavigationSource = PageNavigationSource.Device;

            foreach (var destroyPage in pagesToDestroy)
            {
                MvvmHelpers.OnNavigatedFrom(destroyPage, parameters);
                MvvmHelpers.DestroyPage(destroyPage);
            }

View on GitHub (pinned to 358118cd64)