deepset-ai/haystack · error · ValueError

At least one of row_split_threshold or column_split_threshol

Error message

At least one of row_split_threshold or column_split_threshold must be specified.

What it means

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.

Source

Thrown at haystack/components/preprocessors/csv_document_splitter.py:67

            See https://pandas.pydata.org/docs/reference/api/pandas.read_csv.html for more information.
        :param split_mode:
            If `threshold`, the component will split the document based on the number of
            consecutive empty rows or columns that exceed the `row_split_threshold` or `column_split_threshold`.
            If `row-wise`, the component will split each row into a separate sub-table.
        """
        pandas_import.check()
        if split_mode not in get_args(SplitMode):
            raise ValueError(
                f"Split mode '{split_mode}' not recognized. Choose one among: {', '.join(get_args(SplitMode))}."
            )
        if row_split_threshold is not None and row_split_threshold < 1:
            raise ValueError("row_split_threshold must be greater than 0")

        if column_split_threshold is not None and column_split_threshold < 1:
            raise ValueError("column_split_threshold must be greater than 0")

        if row_split_threshold is None and column_split_threshold is None:
            raise ValueError("At least one of row_split_threshold or column_split_threshold must be specified.")

        self.row_split_threshold = row_split_threshold
        self.column_split_threshold = column_split_threshold
        self.read_csv_kwargs = read_csv_kwargs or {}
        self.split_mode = split_mode

    @component.output_types(documents=list[Document])
    def run(self, documents: list[Document]) -> dict[str, list[Document]]:
        """
        Processes and splits a list of CSV documents into multiple sub-tables.

        **Splitting Process:**
        1. Applies a row-based split if `row_split_threshold` is provided.
        2. Applies a column-based split if `column_split_threshold` is provided.
        3. If both thresholds are specified, performs a recursive split by rows first, then columns, ensuring
           further fragmentation of any sub-tables that still contain empty sections.
        4. Sorts the resulting sub-tables based on their original positions within the document.

View on GitHub (pinned to e318778c9b)

Solutions

  1. Provide a positive row_split_threshold, column_split_threshold, or both.
  2. Use split_mode='row-wise' or 'column-wise' if you intended mode-based splitting and set a matching threshold accordingly.
  3. Default the config values, e.g. row_split_threshold = cfg.get('row_split_threshold', 2).

Example fix

// before
CSVDocumentSplitter(split_mode="threshold")
// after
CSVDocumentSplitter(split_mode="threshold", row_split_threshold=2)
Defensive patterns

Strategy: validation

Validate before calling

if row_split_threshold is None and column_split_threshold is None:
    raise ValueError("specify row_split_threshold or column_split_threshold")
splitter = CSVDocumentSplitter(split_mode="threshold", row_split_threshold=row_t, column_split_threshold=col_t)

Type guard

def has_split_criteria(row: int | None, col: int | None) -> bool:
    return row is not None or col is not None

Try / catch

try:
    splitter = CSVDocumentSplitter(split_mode=mode, row_split_threshold=row_t, column_split_threshold=col_t)
except ValueError as e:
    if "At least one" in str(e):
        splitter = CSVDocumentSplitter(split_mode="threshold", row_split_threshold=2)
    else:
        raise

Prevention

When it happens

Trigger: CSVDocumentSplitter(split_mode='threshold') (or any mode) with neither threshold provided, or both explicitly set to None.

Common situations: 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.

Understand the failure class

Background: "must be positive", "Invalid value": how libraries reject invalid parameter values (ValueError, ArgumentError, INVALID_PARAMETER_VALUE) — this error's family across 28 libraries.

Related errors


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