{"record":{"id":"746e3693263d4973","repo":"dotnet/machinelearning","slug":"expected-a-seekable-stream","errorCode":null,"errorMessage":"Expected a seekable stream","messagePattern":"Expected a seekable stream","errorType":"validation","errorClass":"System.ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.Data.Analysis/DataFrame.IO.cs","lineNumber":576,"sourceCode":"        /// <param name=\"dataTypes\">column types (can be empty)</param>\n        /// <param name=\"numberOfRowsToRead\">number of rows to read not including the header(if present)</param>\n        /// <param name=\"guessRows\">number of rows used to guess types</param>\n        /// <param name=\"addIndexColumn\">add one column with the row index</param>\n        /// <param name=\"encoding\">The character encoding. Defaults to UTF8 if not specified</param>\n        /// <param name=\"renameDuplicatedColumns\">If set to true, columns with repeated names are auto-renamed.</param>\n        /// <param name=\"cultureInfo\">culture info for formatting values</param>\n        /// <param name=\"guessTypeFunction\">function used to guess the type of a column based on its values</param>\n        /// <returns><see cref=\"DataFrame\"/></returns>\n        public static DataFrame LoadCsv(Stream csvStream,\n                                char separator = ',', bool header = true,\n                                string[] columnNames = null, Type[] dataTypes = null,\n                                long numberOfRowsToRead = -1, int guessRows = 10, bool addIndexColumn = false,\n                                Encoding encoding = null, bool renameDuplicatedColumns = false, CultureInfo cultureInfo = null,\n                                Func<IEnumerable<string>, Type> guessTypeFunction = null)\n        {\n            if (!csvStream.CanSeek)\n            {\n                throw new ArgumentException(Strings.NonSeekableStream, nameof(csvStream));\n            }\n\n            if (dataTypes == null && guessRows <= 0)\n            {\n                throw new ArgumentException(string.Format(Strings.ExpectedEitherGuessRowsOrDataTypes, nameof(guessRows), nameof(dataTypes)));\n            }\n\n            WrappedStreamReaderOrStringReader wrappedStreamReaderOrStringReader = new WrappedStreamReaderOrStringReader(csvStream, encoding ?? Encoding.UTF8);\n            return ReadCsvLinesIntoDataFrame(wrappedStreamReaderOrStringReader, separator, header, columnNames, dataTypes, numberOfRowsToRead, guessRows, addIndexColumn, renameDuplicatedColumns, cultureInfo, guessTypeFunction);\n        }\n\n        /// <summary>\n        /// Writes a DataFrame into a CSV.\n        /// </summary>\n        /// <param name=\"dataFrame\"><see cref=\"DataFrame\"/></param>\n        /// <param name=\"path\">CSV file path</param>\n        /// <param name=\"separator\">column separator</param>\n        /// <param name=\"header\">has a header or not</param>","sourceCodeStart":558,"sourceCodeEnd":594,"githubUrl":"https://github.com/dotnet/machinelearning/blob/7b76e69cf964daeca3f1377af6bc5543284d56c6/src/Microsoft.Data.Analysis/DataFrame.IO.cs#L558-L594","documentation":"LoadCsv requires a seekable stream because the CSV reader needs to rewind/re-read rows for header detection and type guessing. If csvStream.CanSeek is false, it throws ArgumentException(Strings.NonSeekableStream, nameof(csvStream)) = 'Expected a seekable stream'. Non-seekable streams (e.g. network or stdin streams) cannot be used directly.","triggerScenarios":"Passing a non-seekable Stream — the raw body stream of an HTTP response, Console.OpenStandardInput(), a decryption stream, or a pipe — to DataFrame.LoadCsv.","commonSituations":"Reading CSV directly from HttpResponse content stream or a WebSocket; piping data via stdin; wrapping a decompressing GZipStream over a network stream where CanSeek is false.","solutions":["Copy the stream into a MemoryStream first (stream.CopyTo(ms); ms.Position = 0), then LoadCsv from the MemoryStream","Write the input to a temporary file and use the file-path LoadCsv overload","If the source is HTTP, read the full body into memory or a file before parsing","Buffer with a seekable wrapper only if buffering is acceptable memory-wise; otherwise stream-parse manually"],"exampleFix":"// before\nvar df = DataFrame.LoadCsv(responseStream);\n// after\nusing var ms = new MemoryStream();\nresponseStream.CopyTo(ms);\nms.Position = 0;\nvar df = DataFrame.LoadCsv(ms);","handlingStrategy":"validation","validationCode":"if (!stream.CanSeek) { var ms = new MemoryStream(); stream.CopyTo(ms); ms.Position = 0; stream = ms; }","typeGuard":null,"tryCatchPattern":"try { return DataFrame.LoadCsv(csvStream); } catch (ArgumentException ex) when (ex.Message.Contains(\"seekable\")) { using var ms = new MemoryStream(); csvStream.CopyTo(ms); ms.Position = 0; return DataFrame.LoadCsv(ms); }","preventionTips":["Check Stream.CanSeek before calling LoadCsv","Buffer network/pipe streams into MemoryStream or a temp file","Prefer the file-path LoadCsv overload for non-seekable sources"],"tags":["stream","csv","argument"],"backgroundTag":"invalid-argument-value","analyzedSha":"7b76e69cf964daeca3f1377af6bc5543284d56c6","analyzedAt":"2026-09-11T12:35:38.930Z","contentChangedAt":"2026-09-11T12:35:38.930Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}