{"record":{"id":"dfdc3efb80d75571","repo":"dotnet/wpf","slug":"sr-invalidoperation-cantchangejournalownership","errorCode":null,"errorMessage":"SR.InvalidOperation_CantChangeJournalOwnership","messagePattern":"SR\\.InvalidOperation_CantChangeJournalOwnership","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Navigation/NavigationService.cs","lineNumber":562,"sourceCode":"        /// <returns></returns>\n        private static INavigatorBase FindTargetInNavigationWindow(NavigationWindow navigationWindow, string navigatorId)\n        {\n            if (navigationWindow != null)\n            {\n                return navigationWindow.NavigationService.FindTarget(navigatorId);\n            }\n            return null;\n        }\n\n        internal void InvalidateJournalNavigationScope()\n        {\n            // If there is a pending journal navigation (Back/Fwd), the JournalNavigationScope cannot\n            // be changed. (If it is a _new_ navigation, we're OK; it will be recorded in the new\n            // applicable journal.)\n            // _navStatus or _navigateQueueItem are not checked here, because they are set only after\n            // raising the Navigating event, while an event handler might cause journal ownership to change.\n            if (_journalScope != null && _journalScope.Journal.HasUncommittedNavigation)\n                throw new InvalidOperationException(SR.InvalidOperation_CantChangeJournalOwnership);\n\n            _journalScope = null;\n\n            for (int i = ChildNavigationServices.Count - 1; i >= 0; i--)\n            {\n                ((NavigationService)ChildNavigationServices[i]).InvalidateJournalNavigationScope();\n            }\n        }\n\n        internal void OnParentNavigationServiceChanged()\n        {\n            NavigationService oldParent = _parentNavigationService;\n            NavigationService newParent = ((DependencyObject)INavigatorHost).GetValue(NavigationServiceProperty) as NavigationService;\n\n            if (newParent == oldParent)\n                return;\n\n            // Remove from old parent's list","sourceCodeStart":544,"sourceCodeEnd":580,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Navigation/NavigationService.cs#L544-L580","documentation":"NavigationService.InvalidateJournalNavigationScope() detaches the service from its journal, but refuses while a Back/Forward (uncommitted) journal navigation is pending, throwing InvalidOperationException CantChangeJournalOwnership. Changing journal ownership mid-navigation would lose the pending navigation target.","triggerScenarios":"Calling RemoveChild (e.g. detaching a child frame/navigation service from a parent) while _journalScope.Journal.HasUncommittedNavigation is true — a Back or Forward navigation was started but not yet committed.","commonSituations":"Removing/reparenting a Frame from the visual tree in response to navigation events; tearing down navigation hosts in Navigating/FragmentNavigation handlers; dynamic layout that swaps frames during user back/forward clicks.","solutions":["Defer RemoveChild/reparenting until navigation completes (LoadCompleted/NavigationFailed)","Do not call GoBack/GoForward immediately before removing a frame; commit pending navigations first","Restructure so journal ownership changes happen outside navigation event handlers"],"exampleFix":"// before\nnavService.GoBack();\nparent.RemoveChild(frame); // pending back navigation -> throws\n// after\nnavService.GoBack();\nnavService.LoadCompleted += (s, e) => parent.RemoveChild(frame);","handlingStrategy":"validation","validationCode":"bool pending = frame.NavigationService.GetType()\n    .GetProperty(\"Journal\", BindingFlags.NonPublic|BindingFlags.Instance) != null; // in practice: defer removal\nif (isNavigating) DeferRemoval(frame); else parent.RemoveChild(frame);","typeGuard":null,"tryCatchPattern":"try { parent.RemoveChild(frame); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"journal\")) {\n    frame.NavigationService.LoadCompleted += (s, e) => parent.RemoveChild(frame);\n}","preventionTips":["Remove/reparent frames only between navigations (after LoadCompleted)","Never mutate the frame tree from Navigating handlers triggered by Back/Forward","Design teardown code to await idle navigation state"],"tags":["wpf","navigation","journal","lifecycle"],"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-21T21:30:21.729Z"}