{"record":{"id":"311f34a3ea5afcb4","repo":"deepset-ai/haystack","slug":"at-least-one-of-row-split-threshold-or-column-spli","errorCode":null,"errorMessage":"At least one of row_split_threshold or column_split_threshold must be specified.","messagePattern":"At least one of row_split_threshold or column_split_threshold must be specified\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"haystack/components/preprocessors/csv_document_splitter.py","lineNumber":67,"sourceCode":"            See https://pandas.pydata.org/docs/reference/api/pandas.read_csv.html for more information.\n        :param split_mode:\n            If `threshold`, the component will split the document based on the number of\n            consecutive empty rows or columns that exceed the `row_split_threshold` or `column_split_threshold`.\n            If `row-wise`, the component will split each row into a separate sub-table.\n        \"\"\"\n        pandas_import.check()\n        if split_mode not in get_args(SplitMode):\n            raise ValueError(\n                f\"Split mode '{split_mode}' not recognized. Choose one among: {', '.join(get_args(SplitMode))}.\"\n            )\n        if row_split_threshold is not None and row_split_threshold < 1:\n            raise ValueError(\"row_split_threshold must be greater than 0\")\n\n        if column_split_threshold is not None and column_split_threshold < 1:\n            raise ValueError(\"column_split_threshold must be greater than 0\")\n\n        if row_split_threshold is None and column_split_threshold is None:\n            raise ValueError(\"At least one of row_split_threshold or column_split_threshold must be specified.\")\n\n        self.row_split_threshold = row_split_threshold\n        self.column_split_threshold = column_split_threshold\n        self.read_csv_kwargs = read_csv_kwargs or {}\n        self.split_mode = split_mode\n\n    @component.output_types(documents=list[Document])\n    def run(self, documents: list[Document]) -> dict[str, list[Document]]:\n        \"\"\"\n        Processes and splits a list of CSV documents into multiple sub-tables.\n\n        **Splitting Process:**\n        1. Applies a row-based split if `row_split_threshold` is provided.\n        2. Applies a column-based split if `column_split_threshold` is provided.\n        3. If both thresholds are specified, performs a recursive split by rows first, then columns, ensuring\n           further fragmentation of any sub-tables that still contain empty sections.\n        4. Sorts the resulting sub-tables based on their original positions within the document.\n","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/deepset-ai/haystack/blob/e318778c9bf60a1963e3b5f451359655dd696c30/haystack/components/preprocessors/csv_document_splitter.py#L49-L85","documentation":"CSVDocumentSplitter needs at least one splitting criterion. If both row_split_threshold and column_split_threshold are None, the component would have no way to split, so __init__ raises ValueError.","triggerScenarios":"CSVDocumentSplitter(split_mode='threshold') (or any mode) with neither threshold provided, or both explicitly set to None.","commonSituations":"Constructing the splitter from config where thresholds were omitted or stripped; assuming defaults exist (they do not); building the component dynamically and forgetting required parameters.","solutions":["Provide a positive row_split_threshold, column_split_threshold, or both.","Use split_mode='row-wise' or 'column-wise' if you intended mode-based splitting and set a matching threshold accordingly.","Default the config values, e.g. row_split_threshold = cfg.get('row_split_threshold', 2)."],"exampleFix":"// before\nCSVDocumentSplitter(split_mode=\"threshold\")\n// after\nCSVDocumentSplitter(split_mode=\"threshold\", row_split_threshold=2)","handlingStrategy":"validation","validationCode":"if row_split_threshold is None and column_split_threshold is None:\n    raise ValueError(\"specify row_split_threshold or column_split_threshold\")\nsplitter = CSVDocumentSplitter(split_mode=\"threshold\", row_split_threshold=row_t, column_split_threshold=col_t)","typeGuard":"def has_split_criteria(row: int | None, col: int | None) -> bool:\n    return row is not None or col is not None","tryCatchPattern":"try:\n    splitter = CSVDocumentSplitter(split_mode=mode, row_split_threshold=row_t, column_split_threshold=col_t)\nexcept ValueError as e:\n    if \"At least one\" in str(e):\n        splitter = CSVDocumentSplitter(split_mode=\"threshold\", row_split_threshold=2)\n    else:\n        raise","preventionTips":["Always provide at least one threshold when reading from config","Apply a default (e.g. 2) when a config key is missing","Check both thresholds for None before construction"],"tags":["validation","configuration","haystack"],"backgroundTag":"invalid-parameter-value","analyzedSha":"e318778c9bf60a1963e3b5f451359655dd696c30","analyzedAt":"2026-08-30T11:45:20.711Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}