deepset-ai/haystack · error · ValueError
expected_chars_per_line must be at least 1.
Error message
expected_chars_per_line must be at least 1.
What it means
PythonCodeSplitter's __init__ requires expected_chars_per_line >= 1; this estimate drives length-based chunk calculations. Zero or negative estimates are invalid, so ValueError is raised.
Source
Thrown at haystack/components/preprocessors/python_code_splitter.py:130
module-level docstring is kept in place since it is itself a top-level unit.
:param preserve_class_definition: If ``True`` (default), chunks that contain class
members but not the class header are prefixed with the bare class signature
(decorators plus the ``class Foo(...):`` lines) in source order.
:param secondary_split_overlap: Line overlap for the secondary splitter; only used
in the oversized fallback. The primary AST split never adds overlap.
:param secondary_split_length: Lines per chunk for the secondary splitter.
Defaults to ``max_effective_lines`` when ``None``.
:raises ValueError: If any parameter is invalid (negative, zero where positive is
required, or ``min_effective_lines > max_effective_lines``).
"""
if min_effective_lines < 1:
raise ValueError("min_effective_lines must be at least 1.")
if max_effective_lines < 1:
raise ValueError("max_effective_lines must be at least 1.")
if min_effective_lines > max_effective_lines:
raise ValueError("min_effective_lines must not be greater than max_effective_lines.")
if expected_chars_per_line < 1:
raise ValueError("expected_chars_per_line must be at least 1.")
if oversized_factor < 1:
raise ValueError("oversized_factor must be at least 1.")
if secondary_split_overlap < 0:
raise ValueError("secondary_split_overlap must be non-negative.")
if secondary_split_length is not None and secondary_split_length < 1:
raise ValueError("secondary_split_length must be at least 1.")
self.min_effective_lines = min_effective_lines
self.max_effective_lines = max_effective_lines
self.expected_chars_per_line = expected_chars_per_line
self.oversized_factor = oversized_factor
self.strip_docstrings = strip_docstrings
self.preserve_class_definition = preserve_class_definition
self.secondary_split_overlap = secondary_split_overlap
self.secondary_split_length = secondary_split_length
def _effective_lines(self, text: str) -> int:
"""Return the number of *effective lines* for ``text`` (see class docstring)."""View on GitHub (pinned to e318778c9b)
Solutions
- Pass a realistic estimate, e.g. expected_chars_per_line=80.
- Omit the parameter to use the default.
- Clamp computed values: expected_chars_per_line=max(1, int(avg)).
- Fix the upstream statistics code that produced 0 (guard against empty inputs).
Example fix
// before avg = sum(len(l) for l in lines) / max(1, len(lines)) if lines else 0 PythonCodeSplitter(expected_chars_per_line=int(avg)) // after PythonCodeSplitter(expected_chars_per_line=max(1, int(avg)) if avg else 80)
Defensive patterns
Strategy: validation
Validate before calling
sample = [len(l) for l in lines] or [80] expected_chars_per_line = max(1, int(sum(sample) / len(sample)))
Type guard
def is_valid_char_estimate(v) -> bool:
return isinstance(v, int) and not isinstance(v, bool) and v >= 1 Try / catch
try:
splitter = PythonCodeSplitter(expected_chars_per_line=estimate)
except ValueError as e:
logging.warning("Invalid expected_chars_per_line (%s), using 80", e)
splitter = PythonCodeSplitter(expected_chars_per_line=80) Prevention
- Guard average-length computations against empty inputs.
- Never leave numeric config placeholders at 0 in production.
- Clamp with max(1, int(value)).
- Use a realistic default (e.g. 80) when no statistics are available.
When it happens
Trigger: Calling PythonCodeSplitter(expected_chars_per_line=0) or negative, usually from a config default of 0, a failed statistic computation (e.g. mean over an empty corpus), or a division by a zero/huge denominator.
Common situations: Computing average line length from an empty sample, env/config placeholders left at 0, or mistaking the parameter for a boolean/flag.
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.
- oversized_factor must be at least 1.
- secondary_split_overlap must be non-negative.
AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30).
Data as JSON: /api/errors/3a371b92e5582b41.
Report an issue: GitHub.