deepset-ai/haystack · error · ValueError

Variable '{output}' not found in inputs for passthrough rout

Error message

Variable '{output}' not found in inputs for passthrough route '{output_name}'. Ensure '{output}' is passed as an input to the router.

What it means

The matched route has output_passthrough=True, so `output` is treated as a plain variable name looked up directly in the router's kwargs instead of being rendered as a Jinja template. The named variable was not among the run() inputs, so a ValueError is raised identifying the missing variable and output_name.

Source

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

                if not rendered:
                    continue

                # Handle multiple outputs
                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"]]
                )
                output_passthrough = route.get("output_passthrough", False)

                result = {}
                for output, output_type, output_name in zip(outputs, output_types, output_names, strict=True):
                    if output_passthrough:
                        # output is a plain variable name — retrieve directly from kwargs, no Jinja2 processing
                        if output not in kwargs:
                            raise ValueError(  # noqa: TRY301
                                f"Variable '{output}' not found in inputs for passthrough route '{output_name}'. "
                                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

View on GitHub (pinned to e318778c9b)

Solutions

  1. Pass the variable named in the error to run() (e.g. router.run(query=...)).
  2. Fix the route's `output` to name a variable actually supplied to the router.
  3. Fix the pipeline wiring so the upstream output connects to the router input with that name.
  4. Set output_passthrough=False if you want `output` treated as a Jinja template instead of a plain variable name.

Example fix

// before
result = router.run()  # route output='query', passthrough
// after
result = router.run(query=question_text)
Defensive patterns

Strategy: validation

Validate before calling

passthrough_outputs = [o for r in router.routes if r.get("output_passthrough")
                       for o in (r["output"] if isinstance(r["output"], list) else [r["output"]])]
missing = [o for o in passthrough_outputs if o not in kwargs]
assert not missing, f"router inputs missing: {missing}"

Type guard

def passthrough_inputs_satisfied(router, kwargs: dict) -> bool:
    return all(o in kwargs
               for r in router.routes if r.get("output_passthrough")
               for o in (r["output"] if isinstance(r["output"], list) else [r["output"]]))

Try / catch

try:
    result = router.run(**kwargs)
except ValueError as e:
    if "not found in inputs for passthrough route" in str(e):
        kwargs.update(required_passthrough_vars)
        result = router.run(**kwargs)
    else:
        raise

Prevention

When it happens

Trigger: Running ConditionalRouter.run() (or running a pipeline where the router receives connections) when the first fired route uses output_passthrough and its `output` variable name is absent from the router's inputs.

Common situations: Renaming an upstream component's output so the router no longer receives the variable; wiring a pipeline without connecting the variable the passthrough route expects; hand-written routes where output was edited but inputs weren't updated.

Related errors


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