{"record":{"id":"92f3002a7edb5b4d","repo":"deepset-ai/haystack","slug":"csvtodocument-quotechar-must-be-a-single-characte","errorCode":null,"errorMessage":"CSVToDocument: quotechar must be a single character.","messagePattern":"CSVToDocument: quotechar must be a single character\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"haystack/components/converters/csv.py","lineNumber":82,"sourceCode":"        :param conversion_mode:\n            - \"file\" (default): one Document per CSV file whose content is the raw CSV text.\n            - \"row\": convert each CSV row to its own Document (requires `content_column` in `run()`).\n        :param delimiter:\n            CSV delimiter used when parsing in row mode (passed to ``csv.DictReader``).\n        :param quotechar:\n            CSV quote character used when parsing in row mode (passed to ``csv.DictReader``).\n        \"\"\"\n        self.encoding = encoding\n        self.store_full_path = store_full_path\n        self.conversion_mode = conversion_mode\n        self.delimiter = delimiter\n        self.quotechar = quotechar\n\n        # Basic validation\n        if len(self.delimiter) != 1:\n            raise ValueError(\"CSVToDocument: delimiter must be a single character.\")\n        if len(self.quotechar) != 1:\n            raise ValueError(\"CSVToDocument: quotechar must be a single character.\")\n\n    @component.output_types(documents=list[Document])\n    def run(\n        self,\n        sources: list[str | Path | ByteStream],\n        *,\n        content_column: str | None = None,\n        meta: dict[str, Any] | list[dict[str, Any]] | None = None,\n    ) -> dict[str, Any]:\n        \"\"\"\n        Converts CSV files to a Document (file mode) or to one Document per row (row mode).\n\n        :param sources:\n            List of file paths or ByteStream objects.\n        :param content_column:\n            **Required when** ``conversion_mode=\"row\"``.\n            The column name whose values become ``Document.content`` for each row.\n            The column must exist in the CSV header.","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/deepset-ai/haystack/blob/e318778c9bf60a1963e3b5f451359655dd696c30/haystack/components/converters/csv.py#L64-L100","documentation":"CSVToDocument validates at construction time that both delimiter and quotechar are exactly one character, because Python's csv module requires single-character dialect parameters. A longer (or empty) string cannot be passed to csv.reader/DictReader, so the component fails fast in __init__ rather than deep inside run().","triggerScenarios":"Instantiating CSVToDocument(delimiter='||') or CSVToDocument(quotechar='') or any delimiter/quotechar with len != 1, e.g. multi-character separators or copying a quoted delimiter from config.","commonSituations":"Config supplied from YAML/env vars containing a quoted or two-char separator; users trying multi-char delimiters common in other tools (e.g. '|~|'); accidentally passing a Path or list instead of a string.","solutions":["Pass a single-character string, e.g. delimiter=';' or delimiter='\\t'.","For multi-character separators, preprocess/replace the separator before feeding the CSV, or use a different converter.","Ensure the value read from config/env is unquoted and is str, not bytes or list.","Check for accidental leading/trailing characters (e.g. '\\t ' from YAML tab expansion)."],"exampleFix":"// before\ncsv_conv = CSVToDocument(delimiter=\"||\", quotechar=\"\\\"\")\n// after\ncsv_conv = CSVToDocument(delimiter=\"|\", quotechar=\"\\\"\")\n# or preprocess: text = text.replace(\"||\", \"|\") before conversion","handlingStrategy":"validation","validationCode":"def validate_csv_dialect(delim, quote):\n    for name, v in ((\"delimiter\", delim), (\"quotechar\", quote)):\n        if not isinstance(v, str) or len(v) != 1:\n            raise ValueError(f\"CSVToDocument {name} must be a single character, got {v!r}\")\nvalidate_csv_dialect(delimiter, quotechar)","typeGuard":"def is_single_char(v) -> bool:\n    return isinstance(v, str) and len(v) == 1","tryCatchPattern":"try:\n    conv = CSVToDocument(delimiter=delim, quotechar=quote)\nexcept ValueError as e:\n    logger.error(\"Bad CSV dialect: %s\", e)\n    conv = CSVToDocument()  # fall back to defaults","preventionTips":["Validate single-character dialect params from config/env before constructing.","Never wrap delimiters in extra quotes when storing them in YAML/env vars.","Use '\\t' escape for tab, not a literal multi-space string.","Unit-test component construction with your actual config values."],"tags":["python","csv","configuration","valueerror"],"backgroundTag":"invalid-configuration-value","analyzedSha":"e318778c9bf60a1963e3b5f451359655dd696c30","analyzedAt":"2026-08-30T11:45:20.711Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}