deepset-ai/haystack · error · ValueError
Route '{output_name}' type doesn't match expected type
Error message
Route '{output_name}' type doesn't match expected type What it means
validate_output_type=True is enabled and the produced output_value of the fired route does not match the route's declared output_type. Haystack raises ValueError so misconfigured route typing fails loudly instead of passing wrongly-typed data downstream.
Source
Thrown at haystack/components/routers/conditional_router.py:467
f"Ensure '{output}' is passed as an input to the router."
)
output_value = kwargs[output]
else:
# Standard Jinja2 template evaluation
t_output = self._env.from_string(output)
output_value = t_output.render(**kwargs)
# We suppress the exception in case the output is already a string, otherwise
# we try to evaluate it and would fail.
# This must be done cause the output could be different literal structures.
# This doesn't support any user types.
with contextlib.suppress(Exception):
if not self._unsafe:
output_value = ast.literal_eval(output_value)
# Validate output type if needed
if self._validate_output_type and not self._output_matches_type(output_value, output_type):
raise ValueError(f"Route '{output_name}' type doesn't match expected type") # noqa: TRY301
result[output_name] = output_value
return result
except Exception as e:
# If this was a type-validation failure or missing passthrough variable, let it propagate
if isinstance(e, ValueError):
raise
msg = f"Error evaluating condition for route '{route}': {e}"
raise RouteConditionException(msg) from e
raise NoRouteSelectedException(f"No route fired. Routes: {self.routes}")
def _validate_routes(self, routes: list[Route]) -> None:
"""
Validates a list of routes.
View on GitHub (pinned to e318778c9b)
Solutions
- Correct the route's output_type to match what the template/variable actually produces.
- Fix the output template so it renders a literal matching output_type (safe mode relies on ast.literal_eval).
- Set validate_output_type=False if validation is not needed.
- If the mismatch comes from a custom/invalid type, use a type _output_matches_type can handle.
Example fix
// before
Route(condition="query.len > 10", output="{{ query }}", output_type=int, output_name="out")
// after
Route(condition="query.len > 10", output="{{ query }}", output_type=str, output_name="out") Defensive patterns
Strategy: validation
Validate before calling
route = {"condition": "q", "output": "{{ q }}", "output_type": str, "output_name": "out"}
rendered = ast.literal_eval(jinja_env.from_string(route["output"]).render(q="x"))
assert isinstance(rendered, route["output_type"]), "declared output_type mismatch" Type guard
def output_matches(value, expected_type) -> bool:
import typing
return isinstance(value, expected_type) or typing.get_origin(expected_type) is not None and isinstance(value, typing.get_origin(expected_type)) Try / catch
try:
result = router.run(query=q)
except ValueError as e:
if "type doesn't match expected type" in str(e):
result = fallback_router.run(query=q)
else:
raise Prevention
- Only enable validate_output_type when route output types are stable and known.
- Remember safe-mode Jinja renders strings; rely on literal_eval-able output or passthrough for typed values.
- Test each route's rendered output against its output_type in CI.
When it happens
Trigger: ConditionalRouter(validate_output_type=True).run() where the fired route's rendered/evaluated output fails _output_matches_type against output_type (e.g. output is a string but output_type is int, or a Jinja-rendered output isn't literal_eval-able into the declared type).
Common situations: Jinja renders numbers as strings and literal_eval can't coerce them (in safe mode); output_type edited after changing the template; passthrough of an object whose runtime type differs from the declared one; invalid output_type annotations that make the matcher always fail.
Related errors
- Error evaluating condition for route '{route}': {e}
- No route fired. Routes: {self.routes}
- Invalid template for condition: {condition_value!r} (type: {
- tools must be a list of Tool and/or Toolset objects, a Tools
- Invalid Jinja template '{template}': {e}
AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30).
Data as JSON: /api/errors/5cca157777cd53ee.
Report an issue: GitHub.