{"record":{"id":"42272925e81ef934","repo":"dotnet/wpf","slug":"sr-objectdisposed-storeclosed","errorCode":null,"errorMessage":"SR.ObjectDisposed_StoreClosed","messagePattern":"SR\\.ObjectDisposed_StoreClosed","errorType":"exception","errorClass":"ObjectDisposedException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Annotations/Storage/XmlStreamStore.cs","lineNumber":930,"sourceCode":"                XPathNodeIterator iterator = tempNavigator.Select($@\"//{AnnotationXmlConstants.Prefixes.CoreSchemaPrefix}:Annotation[@Id=\"\"{XmlConvert.ToString(id)}\"\"]\", _namespaceManager);\n                if (iterator.MoveNext())\n                {\n                    navigator = (XPathNavigator)iterator.Current;\n                }\n            }\n\n            return navigator;\n        }\n\n        /// <summary>\n        ///    Verifies the store is in a valid state.  Throws exceptions otherwise.\n        /// </summary>\n        private void CheckStatus()\n        {\n            lock (SyncRoot)\n            {\n                if (IsDisposed)\n                    throw new ObjectDisposedException(null, SR.ObjectDisposed_StoreClosed);\n\n                if (_stream == null)\n                    throw new InvalidOperationException(SR.StreamNotSet);\n            }\n        }\n\n        /// <summary>\n        /// Called from flush to serialize all annotations in the map\n        /// notice that delete takes care of the delete action both in the map\n        /// and in the store\n        /// </summary>\n        private void SerializeAnnotations()\n        {\n            List<Annotation> mapAnnotations = _storeAnnotationsMap.FindDirtyAnnotations();\n            foreach (Annotation annotation in mapAnnotations)\n            {\n                XPathNavigator editor = GetAnnotationNodeForId(annotation.Id);\n                if (editor == null)","sourceCodeStart":912,"sourceCodeEnd":948,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Annotations/Storage/XmlStreamStore.cs#L912-L948","documentation":"XmlStreamStore throws an ObjectDisposedException with resource key SR.ObjectDisposed_StoreClosed when CheckStatus() detects the annotation store has already been disposed (IsDisposed == true). The store is unusable after Dispose(); any annotation operation on it is invalid. This guards against operating on a closed backing stream.","triggerScenarios":"Calling AddAnnotation, DeleteAnnotation, GetAnnotation, Flush, FindAnnotationIds, or InternalGetAnnotations after calling Dispose() on the XmlStreamStore instance.","commonSituations":"Disposing a store in a finally/using block and then calling Flush again; storing the store in a long-lived field while disposing it on window close but a background save still references it; double-dispose followed by retry logic that re-invokes store methods.","solutions":["Check store.IsDisposed before every operation and recreate the store from the stream if needed","Ensure Dispose is only called after all annotation work (including Flush) is complete","Restructure so the store lives inside a using block that scopes all annotation operations","Catch ObjectDisposedException and re-open the store on the same stream"],"exampleFix":"// before\nstore.Dispose();\nstore.Flush(); // throws ObjectDisposedException\n\n// after\nif (!store.IsDisposed)\n{\n    store.Flush();\n}\nstore.Dispose();","handlingStrategy":"try-catch","validationCode":"if (store.IsDisposed) { store = RecreateStore(); }\nif (!store.IsDisposed) store.Flush();","typeGuard":"bool Usable(XmlStreamStore s) => s != null && !s.IsDisposed;","tryCatchPattern":"try { store.Flush(); }\ncatch (ObjectDisposedException) { store = RecreateStore(); }","preventionTips":["Scope the store in a using block containing all annotation operations","Never cache the store beyond its disposal point; resolve it via a factory","Check IsDisposed before every call in long-lived code paths"],"tags":["wpf","annotations","disposed-object","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"}