{"record":{"id":"8f985fac2b6340e4","repo":"deepset-ai/haystack","slug":"csvtodocument-row-could-not-parse-csv-rows-for","errorCode":null,"errorMessage":"CSVToDocument(row): could not parse CSV rows for {source}: {e}","messagePattern":"CSVToDocument\\(row\\): could not parse CSV rows for (.+?): (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"haystack/components/converters/csv.py","lineNumber":173,"sourceCode":"                if size_bytes > _ROW_MODE_SIZE_WARN_BYTES:\n                    logger.warning(\n                        \"CSVToDocument(row): parsing a large CSV (~{mb:.1f} MB). \"\n                        \"Consider chunking/streaming if you hit memory issues.\",\n                        mb=size_bytes / (1024 * 1024),\n                    )\n            except Exception:\n                pass\n\n            # Create DictReader; if this fails, raise (no fallback)\n            try:\n                # ``restkey`` ensures surplus fields on ragged rows (rows with more values than the\n                # header, e.g. an unquoted comma inside a value) land under an explicit string key\n                # instead of the default ``None`` key, which would break ``Document`` id generation.\n                reader = csv.DictReader(\n                    io.StringIO(data), delimiter=self.delimiter, quotechar=self.quotechar, restkey=\"extra_columns\"\n                )\n            except Exception as e:\n                raise RuntimeError(f\"CSVToDocument(row): could not parse CSV rows for {source}: {e}\") from e\n\n            # Validate header contains content_column; strict error if missing\n            header = reader.fieldnames or []\n            if content_column not in header:\n                raise ValueError(\n                    f\"CSVToDocument(row): content_column='{content_column}' not found in header \"\n                    f\"for {source}. Available columns: {header}\"\n                )\n\n            # Build documents; if a row processing fails, raise immediately (no skip)\n            for i, row in enumerate(reader):\n                try:\n                    doc = self._build_document_from_row(\n                        row=row, base_meta=merged_metadata, row_index=i, content_column=content_column\n                    )\n                except Exception as e:\n                    raise RuntimeError(f\"CSVToDocument(row): failed to process row {i} for {source}: {e}\") from e\n                documents.append(doc)","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/deepset-ai/haystack/blob/e318778c9bf60a1963e3b5f451359655dd696c30/haystack/components/converters/csv.py#L155-L191","documentation":"When DictReader construction fails, CSVToDocument wraps any exception in a RuntimeError that names the offending source. This is a wrapper around parsing errors such as IO failures or bad dialect parameters interacting with the data.","triggerScenarios":"run() with conversion_mode='row' on a source whose CSV cannot be parsed by csv.DictReader with the configured delimiter/quotechar — e.g. a decoding error, an IO error opening the stream, or malformed dialect chars.","commonSituations":"Binary/encoded (non-UTF-8) CSV bytes; wrong delimiter making the parser raise; corrupted downloads; passing ByteStream data that is actually JSON or Excel.","solutions":["Read the chained exception (from e) message to identify the root cause.","Verify the file is valid CSV text in the expected encoding (decode/convert to UTF-8 first).","Check that delimiter/quotechar match the actual file dialect.","Open the file in a CSV viewer/pandas to confirm it parses."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"import csv, io\ndef is_parseable_csv(data: bytes, delimiter: str = \",\", quotechar: str = '\"') -> bool:\n    try:\n        text = data.decode(\"utf-8\")\n        next(csv.reader(io.StringIO(text), delimiter=delimiter, quotechar=quotechar))\n        return True\n    except (UnicodeDecodeError, csv.Error, StopIteration):\n        return False","typeGuard":"def looks_like_csv(data: bytes) -> bool:\n    try:\n        text = data.decode(\"utf-8\")\n    except UnicodeDecodeError:\n        return False\n    first = text.splitlines()[0] if text else \"\"\n    return (\",\" in first or \";\" in first or \"\\t\" in first)","tryCatchPattern":"try:\n    result = conv.run(sources=[stream])\nexcept RuntimeError as e:\n    logger.exception(\"CSV parse failed: %s\", e)  # cause is chained via __cause__\n    raise","preventionTips":["Ensure sources are UTF-8 text CSVs, not Excel/binary exports.","Verify delimiter/quotechar against a sample of the real file.","Pre-decode bytes and normalize encoding before conversion.","Inspect e.__cause__ to find the underlying csv error."],"tags":["python","csv","parsing","runtimeerror"],"backgroundTag":"csv-parse-failed","analyzedSha":"e318778c9bf60a1963e3b5f451359655dd696c30","analyzedAt":"2026-08-30T11:45:20.711Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}