deepset-ai/haystack · error · RouteConditionException

Error evaluating condition for route '{route}': {e}

Error message

Error evaluating condition for route '{route}': {e}

What it means

While evaluating a route's Jinja condition in run(), an unexpected exception occurred (anything other than a ValueError, which propagates unchanged). Haystack wraps it in RouteConditionException with the route and original error in the message, chained as __cause__.

Source

Thrown at haystack/components/routers/conditional_router.py:478

                        # 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.

        :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:

View on GitHub (pinned to e318778c9b)

Solutions

  1. Read the chained __cause__ to see the underlying Jinja error.
  2. Ensure every variable used in the condition is passed to run() and to the router's inputs in the pipeline.
  3. Fix template syntax/typos in the route's condition.
  4. Catch RouteConditionException (and optionally NoRouteSelectedException) around pipeline.run()/router.run() to handle routing failures.

Example fix

// before
router.run()  # condition uses 'query'
// after
router.run(query="hello")
Defensive patterns

Strategy: try-catch

Validate before calling

for r in router.routes:
    for var in re.findall(r"\w+", r["condition"]):
        if var not in RESERVED and var not in kwargs:
            raise KeyError(f"condition variable '{var}' not in inputs")

Type guard

def condition_vars_supplied(router, kwargs: dict) -> bool:
    import re, jinja2
    env = jinja2.Environment()
    for r in router.routes:
        names = jinja2.meta.find_undeclared_variables(env.parse(r["condition"]))
        if not names.issubset(kwargs.keys()):
            return False
    return True

Try / catch

try:
    result = router.run(**kwargs)
except RouteConditionException as e:
    logger.warning("route condition failed: %s", e.__cause__)
    result = default_route_result

Prevention

When it happens

Trigger: Condition template references a variable not passed to run() (Jinja undefined renders, then literal_eval or comparison fails); template syntax or runtime errors; in unsafe mode, NativeEnvironment code raising inside the condition.

Common situations: Forgetting to pass all condition variables to run(); typos in variable names inside condition templates; non-boolean-rendering conditions that break ast.literal_eval in safe mode.

Related errors


AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30). Data as JSON: /api/errors/d40bf4ae480cbdc3. Report an issue: GitHub.