deepset-ai/haystack · error
CSVToDocument(row): content_column='{content_column}' not fo
Error message
CSVToDocument(row): content_column='{content_column}' not found in header for {source}. Available columns: {header} What it means
In row mode the component is strict: the content_column supplied to run() must appear in the CSV header, otherwise it cannot know which field holds the document text. The error lists the actual header columns found.
Source
Thrown at haystack/components/converters/csv.py:178
)
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)
return {"documents": documents}
# ----- helpers -----
def _safe_value(self, value: Any) -> str:View on GitHub (pinned to e318778c9b)
Solutions
- Set content_column to a name exactly matching a header field (case-sensitive).
- Inspect the 'Available columns' list in the message and pick the right one.
- Fix delimiter/quotechar so the header parses into the correct fields.
- Add or regenerate the header row in the CSV file.
Example fix
// before csv_conv.run(sources=[f], content_column="Body") // after (header is: id,text) csv_conv.run(sources=[f], content_column="text")
Defensive patterns
Strategy: validation
Validate before calling
import csv, io
def ensure_content_column(data: bytes, content_column: str, delimiter: str = ",") -> None:
header = next(csv.reader(io.StringIO(data.decode("utf-8")), delimiter=delimiter)) or []
if content_column not in header:
raise ValueError(f"content_column {content_column!r} not in header {header}") Try / catch
try:
result = conv.run(sources=[f], content_column=col)
except ValueError as e:
if "not found in header" in str(e):
col = col.lower() # retry with normalized case or pick a column you parse from the header
result = conv.run(sources=[f], content_column=col)
else:
raise Prevention
- Match header names exactly (case-sensitive); check for typos.
- Fix delimiter so the header parses into correct fields.
- Ensure CSV files include a header row.
- Normalize column names upstream before ingestion.
When it happens
Trigger: run(sources=[...], content_column='body') on a CSV whose header row lacks 'body' — due to typo, case mismatch, wrong delimiter mangling the header, or a missing header row.
Common situations: Renamed columns upstream; case-sensitive mismatch ('Text' vs 'text'); delimiter mismatch causing the whole first line to be one field; CSV without a header at all.
Related errors
- CSVToDocument: quotechar must be a single character.
- CSVToDocument(row): 'content_column' is required in run() wh
- No tools were configured for the Agent at initialization.
- CSVToDocument(row): could not parse CSV rows for {source}: {
- CSVToDocument(row): failed to process row {i} for {source}:
AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30).
Data as JSON: /api/errors/3255726936dadb15.
Report an issue: GitHub.