dotnet/wpf · error · InvalidOperationException
SR.WindowAlreadyClosed
Error message
SR.WindowAlreadyClosed
What it means
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.
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.
Example fix
// before
void child_Return(object s, ReturnEventArgs<object> e) { window.Close(); this.OnReturn(e); }
// after
void child_Return(object s, ReturnEventArgs<object> e) { this.OnReturn(e); window.Close(); } Defensive patterns
Strategy: try-catch
Validate before calling
if (window == null || !window.IsLoaded) { /* skip OnReturn */ } Type guard
bool CanFinish(Window w) => w != null && w.IsLoaded && !w.IsDisposed();
Try / catch
try { pf.OnReturn(args); }
catch (InvalidOperationException ex) when (ex.Message.Contains("closed"))
{ /* window closed mid-flow: abandon PageFunction chain */ } Prevention
- 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.
When it happens
Trigger: 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.
Common situations: Window.Close() invoked from a child PageFunction; modal dialog closed by OS title-bar while PageFunction flow in progress; finishing PageFunctions in Application shutdown.
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
- SR.InvalidOperation_CannotReenterPageFunction
- SR.ReturnEventHandlerMustBeOnParentPage
- SR.UiLessPageFunctionNotCallingOnReturn
- Cannot read Page properties because it is not in a tree…
- SR.EnumeratorVersionChanged
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/a978ff50a4cdbbcd.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Navigation/NavigationService.cs:3664
EventTrace.EventProvider.TraceEvent(
EventTrace.Event.Wpf_NavigationPageFunctionReturn, EventTrace.Keyword.KeywordHosting, EventTrace.Level.Info,
endingPF.ToString());
}
//
// handle this situation gracefully -
// this happens if someone calls Navigate() and then Finishes
// before we have a chance to navigate.
// Investigate what this is....
Debug.Assert(_navigateQueueItem == null,
"There's a navigation pending - see kusumav for details");
// NOTE: It is not always that endingPF==_bp. A PF may end itself when its child ends. Then
// HandleFinish() will be called for the grandparent PF while _bp is still the child PF.
if (JournalScope == null)
{
throw new InvalidOperationException(SR.WindowAlreadyClosed);
}
Journal journal = JournalScope.Journal;
PageFunctionBase parentPF = null;
int parentIndex = JournalEntryPageFunction.GetParentPageJournalIndex(this, journal, endingPF);
if (endingPF.RemoveFromJournal)
{
DoRemoveFromJournal(endingPF, parentIndex);
}
// If the parent page is a PF, resume it and let it know the child PF returned.
// If it's not a PF, the Return event will be raised later on - see NavigateToParentPage().
if (parentIndex != _noParentPage)
{
JournalEntryPageFunction parentPfEntry = journal[parentIndex] as JournalEntryPageFunction;
if (parentPfEntry != null)View on GitHub (pinned to 81131a70a4)