deepset-ai/haystack · error · ValueError

Split length must be at least 1 character.

Error message

Split length must be at least 1 character.

What it means

RecursiveSplitter validates its parameters via _check_params (called from __init__); split_length must be >= 1. A split_length of 0 or negative would produce empty or infinitely-looping chunks, so construction is rejected.

Source

Thrown at haystack/components/preprocessors/recursive_splitter.py:115

        self.tiktoken_tokenizer: "tiktoken.Encoding" | None = None
        self._is_warmed_up = False

    def warm_up(self) -> None:
        """
        Warm up the sentence tokenizer and tiktoken tokenizer if needed.
        """
        if self._is_warmed_up:
            return
        if "sentence" in self.separators:
            self.nltk_tokenizer = self._get_custom_sentence_tokenizer(self.sentence_splitter_params)
        if self.split_units == "token":
            tiktoken_imports.check()
            self.tiktoken_tokenizer = tiktoken.get_encoding("o200k_base")
        self._is_warmed_up = True

    def _check_params(self) -> None:
        if self.split_length < 1:
            raise ValueError("Split length must be at least 1 character.")
        if self.split_overlap < 0:
            raise ValueError("split_overlap must be greater than or equal to 0.")
        if self.split_overlap >= self.split_length:
            raise ValueError("Overlap cannot be greater than or equal to the chunk size.")
        if not all(isinstance(separator, str) for separator in self.separators):
            raise ValueError("All separators must be strings.")

    @staticmethod
    def _get_custom_sentence_tokenizer(sentence_splitter_params: dict[str, Any]) -> Any:
        from haystack.components.preprocessors.sentence_tokenizer import SentenceSplitter

        return SentenceSplitter(**sentence_splitter_params)

    def _split_chunk(self, current_chunk: str) -> tuple[str, str]:
        """
        Splits a chunk based on the split_length and split_units attribute.

        :param current_chunk: The current chunk to be split.

View on GitHub (pinned to e318778c9b)

Solutions

  1. Set split_length to a positive integer appropriate to the unit (characters or tokens per chunk, e.g. 200-2000).
  2. Clamp dynamic values: max(1, requested).
  3. Verify the config key actually maps to split_length and not another parameter.

Example fix

// before
splitter = RecursiveSplitter(split_length=0)
// after
splitter = RecursiveSplitter(split_length=500)
Defensive patterns

Strategy: validation

Validate before calling

if split_length < 1:
    raise ValueError(f'split_length must be >= 1, got {split_length}')

Type guard

def is_valid_split_length(v) -> bool:
    return isinstance(v, int) and v >= 1

Try / catch

try:
    splitter = RecursiveSplitter(split_length=n)
except ValueError as e:
    logger.error('Invalid split_length: %s', e)
    splitter = RecursiveSplitter(split_length=200)

Prevention

When it happens

Trigger: RecursiveSplitter(split_length=0) or negative, typically from a config file value of 0, a computed value, or confusing split_length units (chars/tokens) and passing a percentage or factor.

Common situations: YAML/env pipeline configs where split_length was left at 0; swapping splitters (e.g. from a component that used a fraction parameter) and reusing old values.

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/ada833fe3813423b. Report an issue: GitHub.