PrismLibrary/Prism · error · NavigationException

NavigationException.IConfirmNavigationReturnedFalse

NavigationException.IConfirmNavigationReturnedFalse

Error message

NavigationException.IConfirmNavigationReturnedFalse

What it means

GoBackInternalAsync calls MvvmHelpers.CanNavigateAsync, which invokes IConfirmNavigationRequest.CanNavigate/CanNavigateAsync on the current page or its ViewModel. When it returns false, Prism refuses the back navigation and throws NavigationException with code IConfirmNavigationReturnedFalse — navigation is aborted before the page is popped.

Solutions

  1. Implement IConfirmNavigationRequest on the page/ViewModel so it returns true once edits are saved or the user confirms.
  2. Save or discard pending changes before calling GoBackAsync so CanNavigate returns true.
  3. Wrap GoBackAsync in try/catch for NavigationException and check the code NavigationException.IConfirmNavigationReturnedFalse to handle the refusal gracefully.
  4. Use SendBackButtonPressed handling or a custom back-button handler to confirm with the user before navigating.

Example fix

// before
await _navigationService.GoBackAsync();
// after
try
{
    await _navigationService.GoBackAsync();
}
catch (NavigationException ex) when (ex.Code == NavigationException.IConfirmNavigationReturnedFalse)
{
    // prompt user to save changes or force-navigate
}
Defensive patterns

Strategy: try-catch

Validate before calling

bool canNavigate = (page as IConfirmNavigationRequest)?.CanNavigate(parameters) ?? true;
if (!canNavigate) { /* handle refusal before calling GoBackAsync */ }

Type guard

bool WillAllowBack(INavigationParameters p) =>
    !(_pageAccessor.Page is IConfirmNavigationRequest c) || c.CanNavigate(p);

Try / catch

try { await _navigationService.GoBackAsync(); }
catch (NavigationException ex) when (ex.Code == NavigationException.IConfirmNavigationReturnedFalse)
{ /* prompt user, save, or force navigation */ }

Prevention

When it happens

Trigger: Calling navigationService.GoBackAsync() (or RemoveAndGoBack) while the page being popped implements IConfirmNavigationRequest and its CanNavigate returns false — commonly a form with unsaved changes.

Common situations: Hardware/software back button triggering GoBackAsync on an editable page whose IConfirmNavigationRequest blocks exit; automated tests navigating back without satisfying the confirm condition; forgetting that CanNavigate returning false throws instead of silently no-op.

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


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

Appendix: source

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

    }

    private async Task<INavigationResult> GoBackInternalAsync(INavigationParameters parameters)
    {
        Page page = null;
        try
        {
            parameters ??= new NavigationParameters();

            NavigationSource = PageNavigationSource.NavigationService;

            page = GetCurrentPage();

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

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

            var dialogModal = IDialogContainer.DialogStack.LastOrDefault();
            if (dialogModal is not null)
            {
                if (dialogModal.Dismiss.CanExecute(null))
                    dialogModal.Dismiss.Execute(null);

                return Notify(NavigationRequestType.GoBack, parameters);
            }

            if (IsRoot(GetPageFromWindow(), page))
            {
                return SendAppToBackground(page);
            }

            bool useModalForDoPop = UseModalGoBack(page, parameters);
            Page previousPage = MvvmHelpers.GetOnNavigatedToTarget(page, Window?.Page, useModalForDoPop);

View on GitHub (pinned to 358118cd64)