deepset-ai/haystack · error · RuntimeError

CSVToDocument(row): could not parse CSV rows for {source}: {

Error message

CSVToDocument(row): could not parse CSV rows for {source}: {e}

What it means

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.

Source

Thrown at haystack/components/converters/csv.py:173

                if size_bytes > _ROW_MODE_SIZE_WARN_BYTES:
                    logger.warning(
                        "CSVToDocument(row): parsing a large CSV (~{mb:.1f} MB). "
                        "Consider chunking/streaming if you hit memory issues.",
                        mb=size_bytes / (1024 * 1024),
                    )
            except Exception:
                pass

            # Create DictReader; if this fails, raise (no fallback)
            try:
                # ``restkey`` ensures surplus fields on ragged rows (rows with more values than the
                # header, e.g. an unquoted comma inside a value) land under an explicit string key
                # instead of the default ``None`` key, which would break ``Document`` id generation.
                reader = csv.DictReader(
                    io.StringIO(data), delimiter=self.delimiter, quotechar=self.quotechar, restkey="extra_columns"
                )
            except Exception as e:
                raise RuntimeError(f"CSVToDocument(row): could not parse CSV rows for {source}: {e}") from e

            # Validate header contains content_column; strict error if missing
            header = reader.fieldnames or []
            if content_column not in header:
                raise ValueError(
                    f"CSVToDocument(row): content_column='{content_column}' not found in header "
                    f"for {source}. Available columns: {header}"
                )

            # Build documents; if a row processing fails, raise immediately (no skip)
            for i, row in enumerate(reader):
                try:
                    doc = self._build_document_from_row(
                        row=row, base_meta=merged_metadata, row_index=i, content_column=content_column
                    )
                except Exception as e:
                    raise RuntimeError(f"CSVToDocument(row): failed to process row {i} for {source}: {e}") from e
                documents.append(doc)

View on GitHub (pinned to e318778c9b)

Solutions

  1. Read the chained exception (from e) message to identify the root cause.
  2. Verify the file is valid CSV text in the expected encoding (decode/convert to UTF-8 first).
  3. Check that delimiter/quotechar match the actual file dialect.
  4. Open the file in a CSV viewer/pandas to confirm it parses.
Defensive patterns

Strategy: try-catch

Validate before calling

import csv, io
def is_parseable_csv(data: bytes, delimiter: str = ",", quotechar: str = '"') -> bool:
    try:
        text = data.decode("utf-8")
        next(csv.reader(io.StringIO(text), delimiter=delimiter, quotechar=quotechar))
        return True
    except (UnicodeDecodeError, csv.Error, StopIteration):
        return False

Type guard

def looks_like_csv(data: bytes) -> bool:
    try:
        text = data.decode("utf-8")
    except UnicodeDecodeError:
        return False
    first = text.splitlines()[0] if text else ""
    return ("," in first or ";" in first or "\t" in first)

Try / catch

try:
    result = conv.run(sources=[stream])
except RuntimeError as e:
    logger.exception("CSV parse failed: %s", e)  # cause is chained via __cause__
    raise

Prevention

When it happens

Trigger: 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.

Common situations: Binary/encoded (non-UTF-8) CSV bytes; wrong delimiter making the parser raise; corrupted downloads; passing ByteStream data that is actually JSON or Excel.

Related errors


AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30). Data as JSON: /api/errors/8f985fac2b6340e4. Report an issue: GitHub.