{"record":{"id":"0dc4a9a43e037f4f","repo":"dotnet/wpf","slug":"streaminfo-object-was-disposed","errorCode":null,"errorMessage":"StreamInfo object was disposed.","messagePattern":"StreamInfo object was disposed\\.","errorType":"exception","errorClass":"ObjectDisposedException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/WindowsBase/System/IO/Packaging/CompoundFile/StreamInfo.cs","lineNumber":740,"sourceCode":"            IStream cloneStream = null;\n            core.safeIStream.Clone( out cloneStream );\n            cloneStream.Seek( 0, SafeNativeCompoundFileConstants.STREAM_SEEK_SET, out dummy );\n\n            Stream returnStream = \n                BuildStreamOnUnderlyingIStream( cloneStream, access, this );\n\n            core.exposedStream = returnStream;\n\n            return returnStream;\n        }\n\n        // Check whether this StreamInfo object is still valid.  If not, thrown an\n        //  ObjectDisposedException.\n        internal void CheckDisposedStatus()\n        {\n            // Check to see if we're still valid.\n            if( StreamInfoDisposed ) // Null name in core signifies the core object is disposed\n                throw new ObjectDisposedException(null, SR.StreamInfoDisposed);\n        }\n\n        // Check whether this StreamInfo object is still valid.  Return result.\n        internal bool StreamInfoDisposed\n        {\n            get\n            {\n                // Check to see if we're still valid.\n                // Null name in core signifies the core object is disposed.\n                // Also check the parent storage.\n                return (( null == core.streamName ) || parentStorage.StorageDisposed);\n            }\n        }\n\n\n        // If we opened the IStream but haven't publicly exposed any Streams yet (i.e. InternalExists),\n        // check to make sure the access modes match.\n        internal void CheckAccessMode(int grfMode)","sourceCodeStart":722,"sourceCodeEnd":758,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/IO/Packaging/CompoundFile/StreamInfo.cs#L722-L758","documentation":"CheckDisposedStatus throws ObjectDisposedException when the StreamInfo object has been disposed (name nulled in the core). After disposal the object no longer maps to a valid stream in the storage, so further use is invalid.","triggerScenarios":"Calling GetStream, Create, or Delete on a StreamInfo after its parent root/storage was closed or the StreamInfo was disposed (e.g. after Package.Close or StorageRoot.Dispose).","commonSituations":"Holding StreamInfo/PackageStream references beyond a using block around the Package; disposing the package then continuing to write parts in deferred cleanup code.","solutions":["Keep the Package/root open for the lifetime of all StreamInfo operations","Check StreamInfoDisposed (or wrap in try/catch ObjectDisposedException) before use","Re-open the package and re-obtain the StreamInfo after disposal","Restructure code so writes complete inside the using scope"],"exampleFix":"// before\nusing (var pkg = Package.Open(path)) { part = pkg.GetPart(uri); }\npart.GetStream(); // ObjectDisposedException\n// after\nusing (var pkg = Package.Open(path))\n{\n    var part = pkg.GetPart(uri);\n    var s = part.GetStream(); // use inside scope\n}","handlingStrategy":"validation","validationCode":"bool usable = streamInfo != null && !streamInfo.StreamInfoDisposed; // internal; otherwise catch ObjectDisposedException\nif (!usable) throw new InvalidOperationException(\"StreamInfo is disposed; re-open the package.\");","typeGuard":"static bool IsUsable(StreamInfo si) => si != null; // disposed state is internal; pair with try/catch","tryCatchPattern":"try { var s = streamInfo.GetStream(name, FileMode.Open, FileAccess.Read); }\ncatch (ObjectDisposedException) { package = Package.Open(path); streamInfo = package.GetPart(uri).GetStreamInfo(); }","preventionTips":["Scope all package/stream work inside the using block of the Package","Never cache StreamInfo or PackagePart beyond package lifetime","Re-open the package instead of reusing disposed objects"],"tags":["disposed","object-lifetime","packaging"],"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"}