{"record":{"id":"7eda7ec41f2c0972","repo":"stride3d/stride","slug":"stream-cannot-seek","errorCode":null,"errorMessage":"Stream cannot seek","messagePattern":"Stream cannot seek","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/core/Stride.Core.IO/System.IO.Compression.Zip/ZipFile.cs","lineNumber":82,"sourceCode":"        {\n            this.FileName = filename;\n        }\n\n        /// <summary>\n        /// Initializes a new instance of the <see cref=\"ZipFile\"/> class. \n        /// Method to open an existing storage from stream\n        /// </summary>\n        /// <param name=\"stream\">\n        /// Already opened stream with zip contents\n        /// </param>\n        /// <returns>\n        /// A valid ZipFile object\n        /// </returns>\n        public ZipFile(Stream stream)\n        {\n            if (!stream.CanSeek)\n            {\n                throw new InvalidOperationException(\"Stream cannot seek\");\n            }\n\n            this.zipFileStream = stream;\n\n            if (!this.ReadFileInfo())\n            {\n                throw new Exception();\n            }\n\n            this.FileName = string.Empty;\n        }\n\n        #endregion\n\n        #region Public Properties\n\n        /// <summary>\n        /// Gets the number of entries in the zip file.","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/core/Stride.Core.IO/System.IO.Compression.Zip/ZipFile.cs#L64-L100","documentation":"The ZipFile(Stream) constructor needs to seek backward to locate the end-of-central-directory record. A non-seekable stream (e.g. network or pipe stream) cannot be read as an archive, so the constructor throws immediately.","triggerScenarios":"Constructing ZipFile from a raw NetworkStream, the body of an HTTP response stream read directly, a compressed/deflate stream, or a console/pipe stream.","commonSituations":"Downloading a zip directly into ZipFile without buffering, wrapping a GZipStream and passing it as the zip stream.","solutions":["Copy the stream into a MemoryStream or a temporary FileStream first, then open the ZipFile over that","For HTTP, use a stream that supports seeking (e.g. write response to disk)","Check stream.CanSeek before constructing to give a clearer error"],"exampleFix":"// before\nusing var zip = new ZipFile(responseStream);\n// after\nusing var ms = new MemoryStream();\nresponseStream.CopyTo(ms);\nms.Position = 0;\nusing var zip = new ZipFile(ms);","handlingStrategy":"validation","validationCode":"if (!stream.CanSeek) { using var ms = new MemoryStream(); stream.CopyTo(ms); ms.Position = 0; return new ZipFile(ms); }","typeGuard":"static bool IsSeekable(Stream s) => s.CanSeek;","tryCatchPattern":"try { zip = new ZipFile(stream); }\ncatch (InvalidOperationException) { /* buffer to MemoryStream and retry */ }","preventionTips":["Check stream.CanSeek before archive APIs","Buffer network/pipe/deflate streams to disk or memory before opening archives","Document that ZipFile requires a seekable stream"],"tags":["io","zip","stream"],"backgroundTag":"unsupported-operation","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}