{"record":{"id":"518f2cc20ec770bb","repo":"deepset-ai/haystack","slug":"invalid-template-for-condition-condition-value","errorCode":null,"errorMessage":"Invalid template for condition: {condition_value}","messagePattern":"Invalid template for condition: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"haystack/components/routers/conditional_router.py","lineNumber":519,"sourceCode":"            # Validate outputs are consistent\n            outputs = route[\"output\"] if isinstance(route[\"output\"], list) else [route[\"output\"]]\n            output_types = route[\"output_type\"] if isinstance(route[\"output_type\"], list) else [route[\"output_type\"]]\n            output_names = route[\"output_name\"] if isinstance(route[\"output_name\"], list) else [route[\"output_name\"]]\n\n            # Check lengths match\n            if not len(outputs) == len(output_types) == len(output_names):\n                raise ValueError(f\"Route output, output_type and output_name must have same length: {route}\")\n\n            # Condition is always a Jinja2 template — validate it\n            if not self._validate_template(self._env, route[\"condition\"]):\n                condition_value = route[\"condition\"]\n                if not isinstance(condition_value, str):\n                    raise ValueError(\n                        f\"Invalid template for condition: {condition_value!r} (type: {type(condition_value).__name__}).\"\n                        f\"Condition must be a string representing a valid Jinja2 template. \"\n                        f\"For example, use {str(condition_value)!r} instead of {condition_value!r}.\"\n                    )\n                raise ValueError(f\"Invalid template for condition: {condition_value}\")\n\n            # Only validate output as Jinja2 template when output_passthrough is False (default)\n            output_passthrough = route.get(\"output_passthrough\", False)\n            if not output_passthrough:\n                for output in outputs:\n                    if not self._validate_template(self._env, output):\n                        if not isinstance(output, str):\n                            raise ValueError(\n                                f\"Invalid template for output: {output!r} (type: {type(output).__name__}). \"\n                                f\"Output must be a string representing a valid Jinja2 template. \"\n                                f\"For example, use {str(output)!r} instead of {output!r}.\"\n                            )\n                        raise ValueError(f\"Invalid template for output: {output}\")\n\n    @staticmethod\n    def _extract_variables(env: Environment, templates: list[str]) -> set[str]:\n        \"\"\"\n        Extracts all variables from a list of Jinja template strings.","sourceCodeStart":501,"sourceCodeEnd":537,"githubUrl":"https://github.com/deepset-ai/haystack/blob/e318778c9bf60a1963e3b5f451359655dd696c30/haystack/components/routers/conditional_router.py#L501-L537","documentation":"ConditionalRouter validates every route's 'condition' as a Jinja2 template string during _validate_routes (called from __init__). If the condition value is not a string (or is a string that fails template validation), a ValueError is raised. The specific message here is the fallback raised for non-string conditions or strings failing validation.","triggerScenarios":"Passing a non-string as a route condition, e.g. {'condition': True, ...} or {'condition': 1, ...}, or a string that is not a valid Jinja2 template.","commonSituations":"Building routes programmatically where a boolean condition is passed instead of a template string like '{{ flag }}'; YAML/JSON config loading that yields booleans or None for conditions.","solutions":["Convert the condition to a Jinja2 template string, e.g. use '{{ flag }}' instead of the bare boolean True","Check the exact value repr in the error message; the message suggests the str() version when applicable","Ensure any config/dict sources parse conditions as strings (quote them in YAML)"],"exampleFix":"# before\nConditionalRouter(routes=[{\"condition\": True, \"output\": \"{{ x }}\", \"output_name\": \"ok\", \"output_type\": str}])\n# after\nConditionalRouter(routes=[{\"condition\": \"{{ flag }}\", \"output\": \"{{ x }}\", \"output_name\": \"ok\", \"output_type\": str}])","handlingStrategy":"validation","validationCode":"routes = [{\"condition\": \"{{ flag }}\", \"output\": \"{{ x }}\", \"output_name\": \"ok\", \"output_type\": str}]\nassert all(isinstance(r[\"condition\"], str) for r in routes), \"route condition must be a Jinja2 template string\"","typeGuard":"def is_valid_condition(cond) -> bool:\n    return isinstance(cond, str)","tryCatchPattern":"try:\n    router = ConditionalRouter(routes=routes)\nexcept ValueError as e:\n    if \"Invalid template for condition\" in str(e):\n        routes = [{**r, \"condition\": str(r[\"condition\"])} for r in routes]\n        router = ConditionalRouter(routes=routes)\n    else:\n        raise","preventionTips":["Always write route conditions as Jinja2 template strings like '{{ flag }}'","Quote conditions in YAML/JSON configs so they parse as strings","Construct routes via a helper function that enforces str types"],"tags":["python","validation","jinja2","router"],"backgroundTag":"invalid-template","analyzedSha":"e318778c9bf60a1963e3b5f451359655dd696c30","analyzedAt":"2026-08-30T11:45:20.711Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}