{"record":{"id":"d9a73c529b7558db","repo":"deepset-ai/haystack","slug":"min-effective-lines-must-be-at-least-1","errorCode":null,"errorMessage":"min_effective_lines must be at least 1.","messagePattern":"min_effective_lines must be at least 1\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"haystack/components/preprocessors/python_code_splitter.py","lineNumber":124,"sourceCode":"            ``ceil(len(source) / expected_chars_per_line)``; long lines count as more than one.\n        :param oversized_factor: A function whose effective length exceeds\n            ``oversized_factor * max_effective_lines`` triggers the line-based secondary\n            split with overlap.\n        :param strip_docstrings: If ``True``, function/method/class docstrings are moved\n            from the chunk content into ``meta[\"docstrings\"]`` (source order). The\n            module-level docstring is kept in place since it is itself a top-level unit.\n        :param preserve_class_definition: If ``True`` (default), chunks that contain class\n            members but not the class header are prefixed with the bare class signature\n            (decorators plus the ``class Foo(...):`` lines) in source order.\n        :param secondary_split_overlap: Line overlap for the secondary splitter; only used\n            in the oversized fallback. The primary AST split never adds overlap.\n        :param secondary_split_length: Lines per chunk for the secondary splitter.\n            Defaults to ``max_effective_lines`` when ``None``.\n        :raises ValueError: If any parameter is invalid (negative, zero where positive is\n            required, or ``min_effective_lines > max_effective_lines``).\n        \"\"\"\n        if min_effective_lines < 1:\n            raise ValueError(\"min_effective_lines must be at least 1.\")\n        if max_effective_lines < 1:\n            raise ValueError(\"max_effective_lines must be at least 1.\")\n        if min_effective_lines > max_effective_lines:\n            raise ValueError(\"min_effective_lines must not be greater than max_effective_lines.\")\n        if expected_chars_per_line < 1:\n            raise ValueError(\"expected_chars_per_line must be at least 1.\")\n        if oversized_factor < 1:\n            raise ValueError(\"oversized_factor must be at least 1.\")\n        if secondary_split_overlap < 0:\n            raise ValueError(\"secondary_split_overlap must be non-negative.\")\n        if secondary_split_length is not None and secondary_split_length < 1:\n            raise ValueError(\"secondary_split_length must be at least 1.\")\n\n        self.min_effective_lines = min_effective_lines\n        self.max_effective_lines = max_effective_lines\n        self.expected_chars_per_line = expected_chars_per_line\n        self.oversized_factor = oversized_factor\n        self.strip_docstrings = strip_docstrings","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/deepset-ai/haystack/blob/e318778c9bf60a1963e3b5f451359655dd696c30/haystack/components/preprocessors/python_code_splitter.py#L106-L142","documentation":"PythonCodeSplitter's __init__ validates min_effective_lines: the minimum number of code lines per chunk must be at least 1. Zero or negative values are meaningless for chunking, so ValueError is raised.","triggerScenarios":"Calling PythonCodeSplitter(min_effective_lines=0) or a negative value, often when computing the value dynamically (e.g. multiplying by a zero factor) or copying a config where the field defaulted to 0.","commonSituations":"Zero-initialized config variables, env vars parsed as ints defaulting to 0, or misunderstanding that 0 means 'no minimum' (it is rejected instead).","solutions":["Pass min_effective_lines >= 1, e.g. min_effective_lines=5.","Omit the parameter to use the documented default.","Clamp dynamic values: min_effective_lines=max(1, computed_value).","Fix env/config parsing to use a sane default instead of 0."],"exampleFix":"// before\nPythonCodeSplitter(min_effective_lines=0)\n// after\nPythonCodeSplitter(min_effective_lines=5)","handlingStrategy":"validation","validationCode":"min_effective_lines = max(1, int(min_effective_lines))\nsplitter = PythonCodeSplitter(min_effective_lines=min_effective_lines)","typeGuard":"def is_positive_int(v) -> bool:\n    return isinstance(v, int) and not isinstance(v, bool) and v >= 1","tryCatchPattern":"try:\n    splitter = PythonCodeSplitter(min_effective_lines=min_lines)\nexcept ValueError as e:\n    logging.warning(\"Invalid min_effective_lines (%s), using default\", e)\n    splitter = PythonCodeSplitter()","preventionTips":["Clamp dynamic/config values with max(1, value).","Avoid 0 defaults when parsing env vars; use documented defaults.","Test component construction with each config value in CI."],"tags":["python","validation","constructor-argument","haystack"],"backgroundTag":"invalid-constructor-argument","analyzedSha":"e318778c9bf60a1963e3b5f451359655dd696c30","analyzedAt":"2026-08-30T11:45:20.711Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}