deepset-ai/haystack · error · ValueError
Route must contain 'condition', 'output', 'output_type' and
Error message
Route must contain 'condition', 'output', 'output_type' and 'output_name' fields: {route} What it means
Each route dict must define all four mandatory fields: condition, output, output_type, and output_name. _validate_routes (called from __init__) raises ValueError when any of these keys is missing from a route.
Source
Thrown at haystack/components/routers/conditional_router.py:497
raise NoRouteSelectedException(f"No route fired. Routes: {self.routes}")
def _validate_routes(self, routes: list[Route]) -> None:
"""
Validates a list of routes.
:param routes: A list of routes.
"""
for route in routes:
try:
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__})."View on GitHub (pinned to e318778c9b)
Solutions
- Add the missing field(s) named in the mandatory set to each route dict.
- Validate your route dicts against the required keys before constructing the router.
- If migrating from older configs, add output_name/output_type which newer versions require.
Example fix
// before
{"condition": "x > 1", "output": "out"}
// after
{"condition": "x > 1", "output": "out", "output_type": str, "output_name": "out"} Defensive patterns
Strategy: validation
Validate before calling
REQUIRED = {"condition", "output", "output_type", "output_name"}
for i, r in enumerate(routes):
missing = REQUIRED - set(r.keys())
assert not missing, f"route {i} missing fields: {missing}" Type guard
from typing import TypedDict
class Route(TypedDict):
condition: str
output: str | list
output_type: type | list
output_name: str | list
def routes_conform(routes) -> bool:
return all(set(r.keys()) >= {"condition", "output", "output_type", "output_name"} for r in routes) Try / catch
try:
router = ConditionalRouter(routes=routes)
except ValueError as e:
if "must contain 'condition'" in str(e):
routes = [fill_defaults(r) for r in routes]
router = ConditionalRouter(routes=routes)
else:
raise Prevention
- Use the Route TypedDict/dataclass so type checkers enforce the four mandatory fields.
- Keep a canonical route template and copy it for each new route.
- Validate route YAML against a JSON schema at load time.
When it happens
Trigger: ConditionalRouter(routes=[...]) with a route dict missing one or more of condition/output/output_type/output_name.
Common situations: Copying example routes and deleting fields; hand-written YAML omitting output_name or output_type; refactors that rename keys without updating all routes.
Related errors
- Route must be a dictionary, got: {route}
- Route output, output_type and output_name must have same len
- 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/2257417014b8c2b7.
Report an issue: GitHub.