{"record":{"id":"309ce70b8a647758","repo":"dotnet/wpf","slug":"sr-storageinfodisposed","errorCode":null,"errorMessage":"SR.StorageInfoDisposed","messagePattern":"SR\\.StorageInfoDisposed","errorType":"exception","errorClass":"ObjectDisposedException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/WindowsBase/System/IO/Packaging/CompoundFile/StorageInfo.cs","lineNumber":1258,"sourceCode":"            //  Free unmanaged resources associated with the startCore storage\n            \n            if( null != startCore.safeIStorage)\n            {           \n                ((IDisposable) startCore.safeIStorage).Dispose();\n                startCore.safeIStorage = null;\n            }\n\n            // Null name in core signifies the core object is disposed\n            startCore.storageName = null;\n        }\n    }\n\n    // Check whether this StorageInfo is still valid.  Throw if disposed.\n    internal void CheckDisposedStatus()\n    {\n        // null == parentStorage means we're root.\n        if( StorageDisposed )\n            throw new ObjectDisposedException(null, SR.StorageInfoDisposed);\n    }\n\n    // Check whether this StorageInfo is still valid.\n    internal bool StorageDisposed\n    {\n        get\n        {\n            // null == parentStorage means we're root.\n            if( null != parentStorage )\n            {\n                // Check our core reference to see if we're valid\n                if( null == core.storageName ) // Null name in core signifies the core object is disposed\n                {\n                    // We have been deleted\n                    return true;\n                }\n\n                // We're not the root storage - check parent.","sourceCodeStart":1240,"sourceCodeEnd":1276,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/IO/Packaging/CompoundFile/StorageInfo.cs#L1240-L1276","documentation":"StorageInfo.CheckDisposedStatus throws ObjectDisposedException(null, SR.StorageInfoDisposed) when the underlying StorageRoot has been disposed (StorageDisposed is true). Using any StorageInfo/StreamInfo member after the root container is closed hits this guard.","triggerScenarios":"Disposing or closing the StorageRoot (or the underlying stream/file) and then calling StorageInfo methods such as Exists, enumerators, Open, CreateSubStorage, or Delete on previously obtained child objects.","commonSituations":"Disposing the package/root in a using block but keeping cached StorageInfo/StreamInfo objects for later use; closing the file in a finally while background tasks still read storages.","solutions":["Keep the StorageRoot open as long as any StorageInfo/StreamInfo objects are in use.","Re-open the root and re-fetch storages after disposal instead of reusing old objects.","Check the root's disposed state (e.g. root disposed flag / stream CanRead) before use.","Restructure code so all compound-file work happens inside the root's using scope."],"exampleFix":"// before\nStorageInfo cached;\nusing (var root = StorageRoot.OpenOnStream(stream, FileMode.Open, FileAccess.Read, null))\n    cached = root.GetStorageInfo(\"Data\");\ncached.Exists; // ObjectDisposedException\n// after\nusing (var root = StorageRoot.OpenOnStream(stream, FileMode.Open, FileAccess.Read, null))\n{\n    var cached = root.GetStorageInfo(\"Data\");\n    var exists = cached.Exists; // use inside scope\n}","handlingStrategy":"try-catch","validationCode":"bool usable = rootStream != null && rootStream.CanRead && !rootDisposed;\nif (!usable) throw new InvalidOperationException(\"Container root is closed\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Scope all StorageInfo/StreamInfo usage inside the root's using block.","Do not cache child storages past root disposal.","Track root lifetime explicitly (owner object holds and disposes it last)."],"tags":["io","compound-file","disposed","object-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-21T21:30:21.729Z"}