{"record":{"id":"2220d6b040c889a3","repo":"dotnet/wpf","slug":"sr-seeknotsupported-compressemulationstream","errorCode":null,"errorMessage":"SR.SeekNotSupported","messagePattern":"SR\\.SeekNotSupported","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompressEmulationStream.cs","lineNumber":254,"sourceCode":"        /// <summary>\n        /// Constructor\n        /// </summary>\n        /// <param name=\"baseStream\">part stream - not closed - caller determines lifetime</param>\n        /// <param name=\"position\">current logical stream position</param>\n        /// <param name=\"tempStream\">should be an IsolatedStorageFileStream - not closed - caller determines lifetime</param>\n        /// <param name=\"transformer\">class that does the compression/decompression</param>\n        /// <remarks>This class should only invoked when emulation is required.  \n        /// Does not close any given stream, even when Close is called. This means that it requires\n        /// another wrapper Stream class.</remarks>\n        internal CompressEmulationStream(Stream baseStream, Stream tempStream, long position, IDeflateTransform transformer)\n        {\n            ArgumentOutOfRangeException.ThrowIfNegative(position);\n\n            ArgumentNullException.ThrowIfNull(baseStream);\n\n            // seek and read required for emulation\n            if (!baseStream.CanSeek)\n                throw new InvalidOperationException(SR.SeekNotSupported);\n\n            if (!baseStream.CanRead)\n                throw new InvalidOperationException(SR.ReadNotSupported);\n\n            ArgumentNullException.ThrowIfNull(tempStream);\n            ArgumentNullException.ThrowIfNull(transformer);\n\n            _baseStream = baseStream;\n            _tempStream = tempStream;\n            _transformer = transformer;\n\n            // extract to temporary stream\n            _baseStream.Position = 0;\n            _tempStream.Position = 0;\n            _transformer.Decompress(baseStream, tempStream);\n\n            // seek to the current logical position\n            _tempStream.Position = position;","sourceCodeStart":236,"sourceCodeEnd":272,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompressEmulationStream.cs#L236-L272","documentation":"The CompressEmulationStream constructor requires the base stream to support seeking, because emulating compression on top of it needs both seek and read. A non-seekable base stream causes an InvalidOperationException with SR.SeekNotSupported.","triggerScenarios":"Constructing CompressEmulationStream with a baseStream whose CanSeek is false — e.g. a network stream, a forward-only decompressed stream, or a write-only FileStream.","commonSituations":"Wrapping HTTP response streams or pipes; opening packages directly over non-seekable sources; forwarding a stream from a download before buffering it.","solutions":["Buffer the base stream into a seekable medium first (MemoryStream or FileStream) before constructing.","Check baseStream.CanSeek before constructing and fail with a clear message.","For network sources, download to a temp file and open that."],"exampleFix":"// before\nvar es = new CompressEmulationStream(networkStream, tempStream, transformer);\n// after\nif (!networkStream.CanSeek)\n{\n    var buffered = new MemoryStream();\n    networkStream.CopyTo(buffered);\n    buffered.Position = 0;\n    networkStream = buffered;\n}\nvar es = new CompressEmulationStream(networkStream, tempStream, transformer);","handlingStrategy":"validation","validationCode":"static Stream AsSeekable(Stream source)\n{\n    if (source.CanSeek) return source;\n    var ms = new MemoryStream();\n    source.CopyTo(ms);\n    ms.Position = 0;\n    return ms;\n}","typeGuard":"bool IsSeekableReadable(Stream s) => s != null && s.CanSeek && s.CanRead;","tryCatchPattern":"try { var es = new CompressEmulationStream(baseStream, tempStream, transformer); }\ncatch (InvalidOperationException e) { throw new InvalidDataException(\"Base stream must be seekable and readable; buffer it first\", e); }","preventionTips":["Buffer network/pipe streams into MemoryStream or a temp file before emulating","Check CanSeek before constructing","Prefer opening packages over local files"],"tags":["wpf","stream","seek","nonseekable-stream","io"],"backgroundTag":"unsupported-operation","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-22T01:17:13.364Z"}