{"record":{"id":"0e7b42f8d5b469a0","repo":"dotnet/machinelearning","slug":"a-quoted-field-opened-on-line-linenum-was-never","errorCode":null,"errorMessage":"A quoted field opened on line {lineNum} was never closed, and we've read to the last line in the file without finding the closing quote","messagePattern":"A quoted field opened on line (.+?) was never closed, and we've read to the last line in the file without finding the closing quote","errorType":"exception","errorClass":"EndOfStreamException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.ML.Data/DataLoadSave/Text/TextLoaderCursor.cs","lineNumber":533,"sourceCode":"                        if (line[0] == '/' && line[1] == '/')\n                            return line;\n                        if (ignoreHashLine && line[0] == '#')\n                            return line;\n\n                        // Get more lines until the last field of the line doesn't contain its newline\n                        // inside a quoted field\n                        bool lastFieldIncludesNewLine = LastFieldIncludesNewLine(line, false);\n                        if (!lastFieldIncludesNewLine)\n                            return line;\n\n                        _sb.Clear();\n                        _sb.Append(line);\n                        while (lastFieldIncludesNewLine)\n                        {\n                            line = _rdr.ReadLine();\n\n                            if (line == null)\n                                throw new EndOfStreamException($\"A quoted field opened on line {lineNum} was never closed, and we've read to the last line in the file without finding the closing quote\");\n\n                            _sb.Append(\"\\n\");\n                            _sb.Append(line);\n                            lastFieldIncludesNewLine = LastFieldIncludesNewLine(line, true);\n                        }\n\n                        return _sb.ToString();\n                    }\n\n                    // The startsInsideQuoted parameter indicates if the last field of the previous line\n                    // ended in a quoted field which included the newline character,\n                    // if it is true, then the beginning of this line is considered to be part\n                    // of the last field of the previous line.\n                    public bool LastFieldIncludesNewLine(string line, bool startsInsideQuoted = false)\n                    {\n                        if (line.Length == 0)\n                            return startsInsideQuoted;\n","sourceCodeStart":515,"sourceCodeEnd":551,"githubUrl":"https://github.com/dotnet/machinelearning/blob/7b76e69cf964daeca3f1377af6bc5543284d56c6/src/Microsoft.ML.Data/DataLoadSave/Text/TextLoaderCursor.cs#L515-L551","documentation":"While reading a CSV/text file with quoted fields, TextLoaderCursor.LineReader keeps reading subsequent lines to find the closing quote of a multi-line quoted field. If the stream ends (ReadLine returns null) before the closing quote is found, it throws EndOfStreamException, meaning the file's quoting is malformed or truncated.","triggerScenarios":"Calling LoadFromTextFile / TextLoader on a file where a quote character opens a field on some line (reported as lineNum) and the file ends without the matching closing quote.","commonSituations":"Truncated downloads or partial file writes; CSV data exported with unbalanced quotes; a stray quote character in data (e.g. an inch mark) that the reader interprets as opening a quoted field; wrong separator/quote-char settings misparsing the file.","solutions":["Fix the source file so every quoted field is closed, or remove/escape the stray quote character reported on the given line","Re-export or re-download the file completely and verify it is not truncated","Check the TextLoader quoting settings (quoteChar, hasHeader, separator) match the actual file format"],"exampleFix":"// before: malformed data\n\"name,score\nalice,1\n// after: properly closed quote\n\"name,score\"\nalice,1","handlingStrategy":"validation","validationCode":"static bool HasBalancedQuotes(string line)\n{\n    int count = 0;\n    foreach (char c in line) if (c == '\"') count++;\n    return count % 2 == 0;\n}","typeGuard":null,"tryCatchPattern":"try { data = loader.Load(path); }\ncatch (EndOfStreamException ex) when (ex.Message.Contains(\"quoted field\"))\n{ log.Error(\"Malformed/truncated CSV: unterminated quoted field\", ex); throw new InvalidDataException(\"Source file has unbalanced quotes\", ex); }","preventionTips":["Validate CSV files for balanced quotes before loading (count quote chars per record)","Verify downloaded/exported files are complete (size or checksum check)","Match the loader's quoteChar/separator settings to the actual file format","Escape or remove stray quote characters in source data"],"tags":["csv","text-parsing","end-of-stream"],"backgroundTag":"file-read-failed","analyzedSha":"7b76e69cf964daeca3f1377af6bc5543284d56c6","analyzedAt":"2026-09-11T12:35:38.930Z","contentChangedAt":"2026-09-11T12:35:38.930Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}