deepset-ai/haystack · error · ValueError
split_overlap must be greater than or equal to 0.
Error message
split_overlap must be greater than or equal to 0.
What it means
RecursiveSplitter requires split_overlap >= 0; a negative overlap is meaningless for sliding-window chunking. _check_params runs at construction time so invalid configuration fails immediately.
Source
Thrown at haystack/components/preprocessors/recursive_splitter.py:117
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.
:returns:
A tuple containing the current chunk and the remaining chunk.View on GitHub (pinned to e318778c9b)
Solutions
- Set split_overlap to 0 (no overlap) or a positive value less than split_length.
- Clamp: max(0, computed_overlap).
- Remember overlap must also satisfy split_overlap < split_length (next check).
Example fix
// before splitter = RecursiveSplitter(split_length=200, split_overlap=-10) // after splitter = RecursiveSplitter(split_length=200, split_overlap=20)
Defensive patterns
Strategy: validation
Validate before calling
if split_overlap < 0:
raise ValueError(f'split_overlap must be >= 0, got {split_overlap}') Type guard
def is_valid_overlap(v) -> bool:
return isinstance(v, int) and v >= 0 Try / catch
try:
splitter = RecursiveSplitter(split_length=200, split_overlap=ov)
except ValueError as e:
logger.error('Invalid split_overlap: %s', e)
splitter = RecursiveSplitter(split_length=200, split_overlap=0) Prevention
- Clamp computed overlaps with max(0, value).
- Check sign conventions when migrating from other splitter libraries.
- Validate all splitter params together before construction.
When it happens
Trigger: RecursiveSplitter(split_overlap=-N) with any negative integer; computed overlap values that went negative; sign confusion between 'gap' and 'overlap' semantics.
Common situations: Configs migrated from components where the parameter represented a gap (to be subtracted); arithmetic like split_length - step returning negative.
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
- header_split_levels must be a non-empty list.
- min_effective_lines must be at least 1.
- max_effective_lines must be at least 1.
- expected_chars_per_line must be at least 1.
- oversized_factor must be at least 1.
AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30).
Data as JSON: /api/errors/b2fb0e04182f64bd.
Report an issue: GitHub.