{"record":{"id":"2ddea40971286d5b","repo":"deepset-ai/haystack","slug":"csvtodocument-row-failed-to-process-row-i-for","errorCode":null,"errorMessage":"CSVToDocument(row): failed to process row {i} for {source}: {e}","messagePattern":"CSVToDocument\\(row\\): failed to process row (.+?) for (.+?): (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"haystack/components/converters/csv.py","lineNumber":190,"sourceCode":"            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)\n\n        return {\"documents\": documents}\n\n    # ----- helpers -----\n    def _safe_value(self, value: Any) -> str:\n        \"\"\"Normalize CSV cell values: None -> '', everything -> str.\"\"\"\n        return \"\" if value is None else str(value)\n\n    def _build_document_from_row(\n        self, row: dict[str, Any], base_meta: dict[str, Any], row_index: int, content_column: str\n    ) -> Document:\n        \"\"\"\n        Build a ``Document`` from one parsed CSV row.\n\n        :param row: Mapping of column name to cell value for the current row\n            (as produced by ``csv.DictReader``).\n        :param base_meta: File-level and user-provided metadata to start from","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/deepset-ai/haystack/blob/e318778c9bf60a1963e3b5f451359655dd696c30/haystack/components/converters/csv.py#L172-L208","documentation":"Each row is converted individually; if building a Document from a row raises (e.g. the content cell is missing/None), the component wraps the error in a RuntimeError identifying the row index and source, and stops immediately instead of skipping the row.","triggerScenarios":"conversion_mode='row' where a row lacks the content_column key (short rows via restkey), or _build_document_from_row/_safe_value fails on unexpected row data.","commonSituations":"Ragged CSVs where some rows have fewer fields than the header; rows containing only the delimiter producing None cells; dirty exports with malformed trailing rows.","solutions":["Open the message's row index in the source CSV and fix/clean that row.","Pre-validate the CSV so every row has all header columns (pad short rows).","Use restkey-aware preprocessing or fill missing content cells with a default.","Convert the file with a spreadsheet tool to normalize fields."],"exampleFix":"// before\n# rows with missing trailing cells cause: failed to process row 12\nresult = csv_conv.run(sources=[f], content_column=\"text\")\n// after\nimport csv, io\nrows = list(csv.reader(io.StringIO(f.data.decode(\"utf-8\")))); header = rows[0]\nnormalized = [dict(zip(header, r + [\"\"] * (len(header) - len(r)))) for r in rows[1:]]\n# feed normalized data instead","handlingStrategy":"validation","validationCode":"def validate_ragged_rows(rows, header, content_col):\n    for i, r in enumerate(rows):\n        if len(r) < len(header):\n            raise ValueError(f\"Row {i} has {len(r)} fields, expected {len(header)}\")\n        if r[header.index(content_col)] in (None, \"\"):\n            raise ValueError(f\"Row {i} missing content in {content_col!r}\")","typeGuard":null,"tryCatchPattern":"try:\n    result = conv.run(sources=[f], content_column=col)\nexcept RuntimeError as e:\n    if \"failed to process row\" in str(e):\n        row_idx = int(str(e).split(\"row \")[1].split()[0])\n        logger.error(\"Fix row %d in %s\", row_idx, e)\n    raise","preventionTips":["Clean ragged rows (pad missing cells) before conversion.","Check quoted multi-line fields survive round-trips through export tools.","Validate the CSV with pandas before pipeline ingestion.","Fail-fast locally on a small sample of the production file."],"tags":["python","csv","row-processing","data-quality"],"backgroundTag":"csv-parse-failed","analyzedSha":"e318778c9bf60a1963e3b5f451359655dd696c30","analyzedAt":"2026-08-30T11:45:20.711Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}