{"record":{"id":"a978ff50a4cdbbcd","repo":"dotnet/wpf","slug":"sr-windowalreadyclosed","errorCode":null,"errorMessage":"SR.WindowAlreadyClosed","messagePattern":"SR\\.WindowAlreadyClosed","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Navigation/NavigationService.cs","lineNumber":3664,"sourceCode":"                EventTrace.EventProvider.TraceEvent(\n                    EventTrace.Event.Wpf_NavigationPageFunctionReturn, EventTrace.Keyword.KeywordHosting, EventTrace.Level.Info,\n                    endingPF.ToString());\n            }\n\n            //\n            // handle this situation gracefully -\n            // this happens if someone calls Navigate() and then Finishes\n            // before we have a chance to navigate.\n            // Investigate what this is....\n            Debug.Assert(_navigateQueueItem == null,\n                    \"There's a navigation pending - see kusumav for details\");\n\n            // NOTE: It is not always that endingPF==_bp. A PF may end itself when its child ends. Then\n            // HandleFinish() will be called for the grandparent PF while _bp is still the child PF.\n\n            if (JournalScope == null)\n            {\n                throw new InvalidOperationException(SR.WindowAlreadyClosed);\n            }\n\n            Journal journal = JournalScope.Journal;\n            PageFunctionBase parentPF = null;\n\n            int parentIndex = JournalEntryPageFunction.GetParentPageJournalIndex(this, journal, endingPF);\n\n            if (endingPF.RemoveFromJournal)\n            {\n                DoRemoveFromJournal(endingPF, parentIndex);\n            }\n\n            // If the parent page is a PF, resume it and let it know the child PF returned.\n            // If it's not a PF, the Return event will be raised later on - see NavigateToParentPage().\n            if (parentIndex != _noParentPage)\n            {\n                JournalEntryPageFunction parentPfEntry = journal[parentIndex] as JournalEntryPageFunction;\n                if (parentPfEntry != null)","sourceCodeStart":3646,"sourceCodeEnd":3682,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Navigation/NavigationService.cs#L3646-L3682","documentation":"During PageFunction completion (HandleFinish), the service needs the journal scope to update history, but it is null because the hosting window has already closed. The library cannot finish the PageFunction's Return against a closed window, so it throws.","triggerScenarios":"A PageFunction calls OnReturn/finishes after its hosting Window (and JournalScope) has been closed — e.g. the user closed the window while a child PageFunction was active, and HandleFinish then runs.","commonSituations":"Window.Close() invoked from a child PageFunction; modal dialog closed by OS title-bar while PageFunction flow in progress; finishing PageFunctions in Application shutdown.","solutions":["Ensure the hosting window stays open until the PageFunction chain finishes (handle Closing event to defer).","Call OnReturn before closing the window programmatically.","Check window.IsLoaded / Application state before finishing PageFunctions asynchronously.","Handle the InvalidOperationException and abort the pending PageFunction flow."],"exampleFix":"// before\nvoid child_Return(object s, ReturnEventArgs<object> e) { window.Close(); this.OnReturn(e); }\n// after\nvoid child_Return(object s, ReturnEventArgs<object> e) { this.OnReturn(e); window.Close(); }","handlingStrategy":"try-catch","validationCode":"if (window == null || !window.IsLoaded) { /* skip OnReturn */ }","typeGuard":"bool CanFinish(Window w) => w != null && w.IsLoaded && !w.IsDisposed();","tryCatchPattern":"try { pf.OnReturn(args); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"closed\"))\n{ /* window closed mid-flow: abandon PageFunction chain */ }","preventionTips":["Call OnReturn before any window close logic.","Guard against Closing during PageFunction flows (e.Cancel when a PF is active).","Avoid closing windows from child PageFunction Return handlers.","Await async work before finishing PageFunctions so windows outlive them."],"tags":["wpf","navigation","pagefunction","window-lifetime"],"backgroundTag":"invalid-state-transition","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-22T01:17:13.364Z"}