{"record":{"id":"dd60cc0b774a94ae","repo":"dotnet/wpf","slug":"sr-format-sr-invalidoperation","errorCode":null,"errorMessage":"SR.Format(SR.InvalidOperation_MustImplementIPCCSOrHandleNavigating, _bp != null ? _bp.GetType().ToString() : \"null\")","messagePattern":"SR\\.Format\\(SR\\.InvalidOperation_MustImplementIPCCSOrHandleNavigating, _bp != null \\? _bp\\.GetType\\(\\)\\.ToString\\(\\) : \"null\"\\)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Navigation/NavigationService.cs","lineNumber":1427,"sourceCode":"            }\n            if (_bp == null)\n                throw new InvalidOperationException(SR.InvalidOperation_AddBackEntryNoContent);\n\n            _customContentStateToSave = state;\n            JournalEntry je = UpdateJournal(NavigationMode.New, JournalReason.AddBackEntry, null);\n            // Controls state is not saved by design (saveContent=false). If client applications\n            // require it to be synchronized with the CustomContentState, they can explicitly\n            // include it.\n\n            _customContentStateToSave = null;\n\n            // Since state=null is allowed on input, make sure we get an object either via the\n            // IProvideCustomContentState interface or from a Navigating event handler.\n            // Otherwise it doesn't make sense to add a journal entry.\n            if (je != null && je.CustomContentState == null)\n            {\n                RemoveBackEntry();\n                throw new InvalidOperationException(\n                    SR.Format(SR.InvalidOperation_MustImplementIPCCSOrHandleNavigating,\n                            _bp != null ? _bp.GetType().ToString() : \"null\"));\n            }\n        }\n\n        /// <summary>\n        /// Remove the first JournalEntry from NavigationWindow's back history\n        /// </summary>\n        public JournalEntry RemoveBackEntry()\n        {\n            if (IsDisposed)\n            {\n                return null;\n            }\n            if (JournalScope == null)\n                return null; //(Normally, no exception is thrown if there is no back entry.)\n            return JournalScope.RemoveBackEntry();\n        }","sourceCodeStart":1409,"sourceCodeEnd":1445,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Navigation/NavigationService.cs#L1409-L1445","documentation":"After AddBackEntry() journals the request, the resulting entry must carry a CustomContentState — either because the content implements IProvideCustomContentState or because a Navigating event handler supplied state. If je.CustomContentState is null, the service rolls back (RemoveBackEntry) and throws InvalidOperationException MustImplementIPCCSOrHandleNavigating naming the content type (or \"null\").","triggerScenarios":"Calling AddBackEntry(null) (or relying on it) when the current content object does not implement IProvideCustomContentState and no Navigating handler sets e.ContentStateToSave, so the journal entry ends with CustomContentState == null.","commonSituations":"Copy/pasting AddBackEntry sample code without implementing IProvideCustomContentState on the page class; renaming refactoring that dropped the interface; expecting AddBackEntry(null) to snapshot the page automatically (it does not).","solutions":["Implement IProvideCustomContentState on the navigated content class and return a CustomContentState from GetContentState()","Handle the Navigating event and set e.ContentStateToSave to a CustomContentState instance","Pass an explicit non-null CustomContentState to AddBackEntry(state)"],"exampleFix":"// before\nnavService.AddBackEntry(null); // page does not provide state\n// after\npublic class MyPage : Page, IProvideCustomContentState\n{\n    public CustomContentState GetContentState() => new MyPageState(this);\n}\nnavService.AddBackEntry(null); // now valid via IProvideCustomContentState","handlingStrategy":"validation","validationCode":"bool providesState = navService.Content is IProvideCustomContentState || navigatingHandlerInstalled;\nif (!providesState) navService.AddBackEntry(new MyState()); // explicit state","typeGuard":"bool ContentProvidesState(NavigationService ns) => ns.Content is IProvideCustomContentState;","tryCatchPattern":"try { ns.AddBackEntry(state); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"CustomContentState\")) {\n    // content type must implement IProvideCustomContentState\n}","preventionTips":["Implement IProvideCustomContentState on navigable page classes","Or set NavigatingEventArgs.ContentStateToSave in a Navigating handler","Never rely on AddBackEntry(null) without either mechanism in place"],"tags":["wpf","navigation","customcontentstate","journal"],"backgroundTag":"missing-dependency","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"}