{"record":{"id":"020cd5e812e79c5a","repo":"BerriAI/litellm","slug":"error-rendering-template-prompt-id-e","errorCode":null,"errorMessage":"Error rendering template '{prompt_id}': {e}","messagePattern":"Error rendering template '(.+?)': (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/integrations/dotprompt/prompt_manager.py","lineNumber":224,"sourceCode":"\n        if template is None:\n            available_prompts: Final = list(self.prompts.keys())\n            version_str: Final = f\" (version {version})\" if version else \"\"\n            raise KeyError(f\"Prompt '{prompt_id}'{version_str} not found. Available prompts: {available_prompts}\")\n\n        variables: Final = prompt_variables or {}\n\n        # Validate input variables against schema if defined\n        if template.input_schema:\n            self._validate_input(variables, template.input_schema)\n\n        try:\n            # Create Jinja2 template and render\n            jinja_template: Final = self.jinja_env.from_string(template.content)\n            rendered: Final = jinja_template.render(**variables)\n            return rendered\n        except Exception as e:\n            raise ValueError(f\"Error rendering template '{prompt_id}': {e}\")\n\n    def _validate_input(self, variables: dict[str, Any], schema: dict[str, Any]) -> None:\n        \"\"\"Basic validation of input variables against schema.\"\"\"\n        for field_name, field_type in schema.items():\n            if field_name in variables:\n                value = variables[field_name]\n                expected_type = self._get_python_type(field_type)\n\n                if not isinstance(value, expected_type):\n                    raise ValueError(\n                        f\"Invalid type for field '{field_name}': \"\n                        f\"expected {getattr(expected_type, '__name__', str(expected_type))}, got {type(value).__name__}\"\n                    )\n\n    def _get_python_type(self, schema_type: str) -> type | tuple:\n        \"\"\"Convert schema type string to Python type.\"\"\"\n        type_mapping: Final[dict[str, type | tuple]] = {\n            \"string\": str,","sourceCodeStart":206,"sourceCodeEnd":242,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/integrations/dotprompt/prompt_manager.py#L206-L242","documentation":"PromptManager.render wraps the Jinja2 compile-and-render step in a broad try/except and re-raises any exception as ValueError prefixed with the prompt_id. Rendering happens in an ImmutableSandboxedEnvironment with Handlebars-style delimiters ({{var}}, {% %}, {# #}), so typical causes are Jinja2 syntax errors, sandbox security rejects on unsafe attribute access, and failures raised from filters or attribute lookups during render.","triggerScenarios":"Template body with invalid Jinja2 syntax (unclosed {% if %} without {% endif %}, stray {{); accessing attributes/methods the ImmutableSandboxedEnvironment blocks; a filter applied to a variable of the wrong type; schema validation passed but the template body itself fails mid-render.","commonSituations":"Authoring prompts with Handlebars habits that don't map to Jinja2 blocks; using {{user.name}} where user is a plain dict key or None; escaping/whitespace edits that break delimiters; user-supplied templates submitted via a test endpoint hitting sandbox restrictions.","solutions":["Re-render manually to see the raw cause: jinja2.Environment().from_string(template.content).render(**vars)","Inspect manager.prompts[prompt_id].content and fix the template syntax/delimiters","Supply every variable the template references (or provide defaults in the template: {{var | default('x')}})","Catch ValueError and log the chained __cause__ for the underlying Jinja2 error"],"exampleFix":"# before\nrendered = manager.render('greeting', {'user': user})\n\n# after\ntry:\n    rendered = manager.render('greeting', {'user': user})\nexcept ValueError:\n    logger.exception('render failed for greeting; cause=%s', sys.exc_info()[1].__cause__)\n    raise","handlingStrategy":"try-catch","validationCode":"from jinja2 import Environment\n\ndef template_parses(content: str) -> bool:\n    try:\n        Environment().parse(content)\n        return True\n    except Exception:\n        return False\n\nif not template_parses(manager.prompts[prompt_id].content):\n    raise ValueError(f'prompt {prompt_id} has invalid template syntax')","typeGuard":null,"tryCatchPattern":"try:\n    rendered = manager.render(prompt_id, variables)\nexcept ValueError as e:\n    logger.error('render of %s failed: %s', prompt_id, e.__cause__ or e)\n    raise","preventionTips":["Render every loaded prompt once with sample variables as a startup smoke test","Keep templates simple; avoid attribute chains on possibly-missing values (use {{var | default('...')}})","Log the chained __cause__, which holds the real Jinja2 error"],"tags":["litellm","dotprompt","prompt","jinja2","template-render"],"backgroundTag":"template-render-failed","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}