deepset-ai/haystack · error · ValueError
Route output, output_type and output_name must have same len
Error message
Route output, output_type and output_name must have same length: {route} What it means
When a route uses multiple outputs, output, output_type, and output_name may each be a list; _validate_routes requires all three lists to have equal length so outputs pair up via strict zip at run time. Unequal lengths raise ValueError at construction.
Source
Thrown at haystack/components/routers/conditional_router.py:508
keys = set(route.keys())
except AttributeError as e:
raise ValueError(f"Route must be a dictionary, got: {route}") from e
mandatory_fields = {"condition", "output", "output_type", "output_name"}
has_all_mandatory_fields = mandatory_fields.issubset(keys)
if not has_all_mandatory_fields:
raise ValueError(
f"Route must contain 'condition', 'output', 'output_type' and 'output_name' fields: {route}"
)
# Validate outputs are consistent
outputs = route["output"] if isinstance(route["output"], list) else [route["output"]]
output_types = route["output_type"] if isinstance(route["output_type"], list) else [route["output_type"]]
output_names = route["output_name"] if isinstance(route["output_name"], list) else [route["output_name"]]
# Check lengths match
if not len(outputs) == len(output_types) == len(output_names):
raise ValueError(f"Route output, output_type and output_name must have same length: {route}")
# Condition is always a Jinja2 template — validate it
if not self._validate_template(self._env, route["condition"]):
condition_value = route["condition"]
if not isinstance(condition_value, str):
raise ValueError(
f"Invalid template for condition: {condition_value!r} (type: {type(condition_value).__name__})."
f"Condition must be a string representing a valid Jinja2 template. "
f"For example, use {str(condition_value)!r} instead of {condition_value!r}."
)
raise ValueError(f"Invalid template for condition: {condition_value}")
# Only validate output as Jinja2 template when output_passthrough is False (default)
output_passthrough = route.get("output_passthrough", False)
if not output_passthrough:
for output in outputs:
if not self._validate_template(self._env, output):
if not isinstance(output, str):View on GitHub (pinned to e318778c9b)
Solutions
- Make output, output_type, and output_name lists of the same length.
- If the route has one output, use scalar (non-list) values for all three fields.
- Recount the lists element-by-element after editing a multi-output route.
Example fix
// before
{"output": ["a", "b"], "output_type": [str], "output_name": ["x", "y"]}
// after
{"output": ["a", "b"], "output_type": [str, str], "output_name": ["x", "y"]} Defensive patterns
Strategy: validation
Validate before calling
def norm(v): return v if isinstance(v, list) else [v]
for r in routes:
lens = {len(norm(r["output"])), len(norm(r["output_type"])), len(norm(r["output_name"]))}
assert lens == {norm(r["output"]).__len__()}, "output/output_type/output_name length mismatch" Type guard
def output_lengths_match(route: dict) -> bool:
n = lambda v: v if isinstance(v, list) else [v]
return len(n(route["output"])) == len(n(route["output_type"])) == len(n(route["output_name"])) Try / catch
try:
router = ConditionalRouter(routes=routes)
except ValueError as e:
if "must have same length" in str(e):
routes = [pad_output_lists(r) for r in routes]
router = ConditionalRouter(routes=routes)
else:
raise Prevention
- Edit multi-output routes' three lists together, never one in isolation.
- Write a small lint that checks output/output_type/output_name list lengths in pipeline YAML.
- Prefer scalar values for single-output routes to avoid list-length pitfalls.
When it happens
Trigger: A route dict where output, output_type, or output_name is a list and the three lists differ in length (e.g. 2 outputs, 3 output_names).
Common situations: Multi-output routes where a new output was appended to `output` but not to output_type/output_name; YAML list indentation mistakes producing wrong-length lists.
Related errors
- Route must be a dictionary, got: {route}
- Route must contain 'condition', 'output', 'output_type' and
- Invalid template for condition: {condition_value!r} (type: {
- Invalid template for condition: {condition_value}
- Invalid template for output: {output!r} (type: {type(output)
AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30).
Data as JSON: /api/errors/6e2fdd98430db121.
Report an issue: GitHub.