{"record":{"id":"b2fb0e04182f64bd","repo":"deepset-ai/haystack","slug":"split-overlap-must-be-greater-than-or-equal-to-0-b2fb0e","errorCode":null,"errorMessage":"split_overlap must be greater than or equal to 0.","messagePattern":"split_overlap must be greater than or equal to 0\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"haystack/components/preprocessors/recursive_splitter.py","lineNumber":117,"sourceCode":"\n    def warm_up(self) -> None:\n        \"\"\"\n        Warm up the sentence tokenizer and tiktoken tokenizer if needed.\n        \"\"\"\n        if self._is_warmed_up:\n            return\n        if \"sentence\" in self.separators:\n            self.nltk_tokenizer = self._get_custom_sentence_tokenizer(self.sentence_splitter_params)\n        if self.split_units == \"token\":\n            tiktoken_imports.check()\n            self.tiktoken_tokenizer = tiktoken.get_encoding(\"o200k_base\")\n        self._is_warmed_up = True\n\n    def _check_params(self) -> None:\n        if self.split_length < 1:\n            raise ValueError(\"Split length must be at least 1 character.\")\n        if self.split_overlap < 0:\n            raise ValueError(\"split_overlap must be greater than or equal to 0.\")\n        if self.split_overlap >= self.split_length:\n            raise ValueError(\"Overlap cannot be greater than or equal to the chunk size.\")\n        if not all(isinstance(separator, str) for separator in self.separators):\n            raise ValueError(\"All separators must be strings.\")\n\n    @staticmethod\n    def _get_custom_sentence_tokenizer(sentence_splitter_params: dict[str, Any]) -> Any:\n        from haystack.components.preprocessors.sentence_tokenizer import SentenceSplitter\n\n        return SentenceSplitter(**sentence_splitter_params)\n\n    def _split_chunk(self, current_chunk: str) -> tuple[str, str]:\n        \"\"\"\n        Splits a chunk based on the split_length and split_units attribute.\n\n        :param current_chunk: The current chunk to be split.\n        :returns:\n            A tuple containing the current chunk and the remaining chunk.","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/deepset-ai/haystack/blob/e318778c9bf60a1963e3b5f451359655dd696c30/haystack/components/preprocessors/recursive_splitter.py#L99-L135","documentation":"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.","triggerScenarios":"RecursiveSplitter(split_overlap=-N) with any negative integer; computed overlap values that went negative; sign confusion between 'gap' and 'overlap' semantics.","commonSituations":"Configs migrated from components where the parameter represented a gap (to be subtracted); arithmetic like split_length - step returning negative.","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)."],"exampleFix":"// before\nsplitter = RecursiveSplitter(split_length=200, split_overlap=-10)\n// after\nsplitter = RecursiveSplitter(split_length=200, split_overlap=20)","handlingStrategy":"validation","validationCode":"if split_overlap < 0:\n    raise ValueError(f'split_overlap must be >= 0, got {split_overlap}')","typeGuard":"def is_valid_overlap(v) -> bool:\n    return isinstance(v, int) and v >= 0","tryCatchPattern":"try:\n    splitter = RecursiveSplitter(split_length=200, split_overlap=ov)\nexcept ValueError as e:\n    logger.error('Invalid split_overlap: %s', e)\n    splitter = RecursiveSplitter(split_length=200, split_overlap=0)","preventionTips":["Clamp computed overlaps with max(0, value).","Check sign conventions when migrating from other splitter libraries.","Validate all splitter params together before construction."],"tags":["python","validation","constructor-argument","haystack"],"backgroundTag":"invalid-parameter-value","analyzedSha":"e318778c9bf60a1963e3b5f451359655dd696c30","analyzedAt":"2026-08-30T11:45:20.711Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}