{"record":{"id":"885245c096873d60","repo":"PrismLibrary/Prism","slug":"canclose-returned-false","errorCode":null,"errorMessage":"CanClose returned false","messagePattern":"CanClose returned false","errorType":"exception","errorClass":"DialogException","httpStatus":null,"severity":"warning","filePath":"src/Maui/Prism.Maui/Dialogs/DialogServiceBase.cs","lineNumber":153,"sourceCode":"            PageNavigationService.NavigationSource = PageNavigationSource.DialogService;\n\n            result ??= new DialogResult();\n            if (result.Parameters is null)\n            {\n                result = new DialogResult\n                {\n                    Exception = result.Exception,\n                    Parameters = new DialogParameters(),\n                    Result = result.Result\n                };\n            }\n\n            var view = dialogModal.DialogView;\n            var dialogAware = GetDialogController(view);\n\n            if (!dialogAware.CanCloseDialog())\n            {\n                throw new DialogException(DialogException.CanCloseIsFalse);\n            }\n\n            PageNavigationService.NavigationSource = PageNavigationSource.DialogService;\n            await dialogModal.DoPop(currentPage);\n            PageNavigationService.NavigationSource = PageNavigationSource.Device;\n\n            MvvmHelpers.InvokeViewAndViewModelAction<IActiveAware>(view, aa => aa.IsActive = false);\n            MvvmHelpers.InvokeViewAndViewModelAction<IActiveAware>(currentPage, aa => aa.IsActive = true);\n            dialogAware.OnDialogClosed();\n\n            return result;\n        }\n        catch (DialogException)\n        {\n            throw;\n        }\n        catch (Exception ex)\n        {","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/PrismLibrary/Prism/blob/358118cd640d9a22ff8cf21c8ad197fa038b7990/src/Maui/Prism.Maui/Dialogs/DialogServiceBase.cs#L135-L171","documentation":"CloseDialogAsync first asks the dialog's IDialogAware controller whether it may close via CanCloseDialog(). If that returns false, Prism refuses to close and throws DialogException with the \"CanClose returned false\" message. This is the programmatic path of a user-cancelled close.","triggerScenarios":"Calling dialogService.CloseDialogAsync (or RequestClose flow) on a dialog whose ViewModel's CanCloseDialog() returns false — typically because it has unsaved data or failed validation.","commonSituations":"Programmatically dismissing an edit form dialog whose CanCloseDialog returns false until the user saves; calling close from code without first checking whether the dialog permits closing; assuming CloseDialogAsync always succeeds.","solutions":["Catch DialogException around CloseDialogAsync and treat it as 'dialog declined to close'.","Check the dialog controller's CanCloseDialog (or your VM's close-permission state) before requesting close.","If the close should be forced, change the ViewModel so CanCloseDialog returns true for that path.","Use RequestClose with an IDialogResult so the VM can signal why it refused."],"exampleFix":"// before\nawait dialogService.CloseDialogAsync(dialog);\n// after\ntry { await dialogService.CloseDialogAsync(dialog); }\ncatch (DialogException) { /* dialog's CanCloseDialog returned false — keep it open */ }","handlingStrategy":"try-catch","validationCode":"// inspect your VM state before closing\nbool mayClose = viewModel.CanCloseDialog();\nif (!mayClose) return; // don't call CloseDialogAsync","typeGuard":null,"tryCatchPattern":"try { await dialogService.CloseDialogAsync(); }\ncatch (DialogException ex) when (ex.Message.Contains(\"CanClose\"))\n{ /* dialog declined to close — keep it open */ }","preventionTips":["Check close permission (CanCloseDialog) before programmatically closing.","Design VMs so programmatic close paths set state that allows closing.","Never assume CloseDialogAsync succeeds — it respects the dialog's veto."],"tags":["prism","maui","dialogs","canclose"],"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"}