{"record":{"id":"a4a59f8276f38212","repo":"PrismLibrary/Prism","slug":"navigationexception-iconfirmnavigationreturnedfalse","errorCode":"NavigationException.IConfirmNavigationReturnedFalse","errorMessage":"NavigationException.IConfirmNavigationReturnedFalse","messagePattern":"NavigationException\\.IConfirmNavigationReturnedFalse","errorType":"exception","errorClass":"NavigationException","httpStatus":null,"severity":"error","filePath":"src/Maui/Prism.Maui/Navigation/PageNavigationService.cs","lineNumber":110,"sourceCode":"    }\n\n    private async Task<INavigationResult> GoBackInternalAsync(INavigationParameters parameters)\n    {\n        Page page = null;\n        try\n        {\n            parameters ??= new NavigationParameters();\n\n            NavigationSource = PageNavigationSource.NavigationService;\n\n            page = GetCurrentPage();\n\n            parameters.GetNavigationParametersInternal().Add(KnownInternalParameters.NavigationMode, NavigationMode.Back);\n\n            var canNavigate = await MvvmHelpers.CanNavigateAsync(page, parameters);\n            if (!canNavigate)\n            {\n                throw new NavigationException(NavigationException.IConfirmNavigationReturnedFalse, page);\n            }\n\n            var dialogModal = IDialogContainer.DialogStack.LastOrDefault();\n            if (dialogModal is not null)\n            {\n                if (dialogModal.Dismiss.CanExecute(null))\n                    dialogModal.Dismiss.Execute(null);\n\n                return Notify(NavigationRequestType.GoBack, parameters);\n            }\n\n            if (IsRoot(GetPageFromWindow(), page))\n            {\n                return SendAppToBackground(page);\n            }\n\n            bool useModalForDoPop = UseModalGoBack(page, parameters);\n            Page previousPage = MvvmHelpers.GetOnNavigatedToTarget(page, Window?.Page, useModalForDoPop);","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/PrismLibrary/Prism/blob/358118cd640d9a22ff8cf21c8ad197fa038b7990/src/Maui/Prism.Maui/Navigation/PageNavigationService.cs#L92-L128","documentation":"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.","triggerScenarios":"Calling navigationService.GoBackAsync() (or RemoveAndGoBack) while the page being popped implements IConfirmNavigationRequest and its CanNavigate returns false — commonly a form with unsaved changes.","commonSituations":"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.","solutions":["Implement IConfirmNavigationRequest on the page/ViewModel so it returns true once edits are saved or the user confirms.","Save or discard pending changes before calling GoBackAsync so CanNavigate returns true.","Wrap GoBackAsync in try/catch for NavigationException and check the code NavigationException.IConfirmNavigationReturnedFalse to handle the refusal gracefully.","Use SendBackButtonPressed handling or a custom back-button handler to confirm with the user before navigating."],"exampleFix":"// before\nawait _navigationService.GoBackAsync();\n// after\ntry\n{\n    await _navigationService.GoBackAsync();\n}\ncatch (NavigationException ex) when (ex.Code == NavigationException.IConfirmNavigationReturnedFalse)\n{\n    // prompt user to save changes or force-navigate\n}","handlingStrategy":"try-catch","validationCode":"bool canNavigate = (page as IConfirmNavigationRequest)?.CanNavigate(parameters) ?? true;\nif (!canNavigate) { /* handle refusal before calling GoBackAsync */ }","typeGuard":"bool WillAllowBack(INavigationParameters p) =>\n    !(_pageAccessor.Page is IConfirmNavigationRequest c) || c.CanNavigate(p);","tryCatchPattern":"try { await _navigationService.GoBackAsync(); }\ncatch (NavigationException ex) when (ex.Code == NavigationException.IConfirmNavigationReturnedFalse)\n{ /* prompt user, save, or force navigation */ }","preventionTips":["Implement CanNavigate to return true by default and only block on real unsaved-state conditions","Save or commit state before programmatic back navigation","Always wrap programmatic GoBackAsync in NavigationException handling"],"tags":["navigation","confirm-navigation","prism","xamarin-maui"],"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"}