BerriAI/litellm · error · ValueError

Error rendering template

Error message

Error rendering template '{prompt_id}': {e}

What it means

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.

Solutions

  1. Re-render manually to see the raw cause: jinja2.Environment().from_string(template.content).render(**vars)
  2. Inspect manager.prompts[prompt_id].content and fix the template syntax/delimiters
  3. Supply every variable the template references (or provide defaults in the template: {{var | default('x')}})
  4. Catch ValueError and log the chained __cause__ for the underlying Jinja2 error

Example fix

# before
rendered = manager.render('greeting', {'user': user})

# after
try:
    rendered = manager.render('greeting', {'user': user})
except ValueError:
    logger.exception('render failed for greeting; cause=%s', sys.exc_info()[1].__cause__)
    raise
Defensive patterns

Strategy: try-catch

Validate before calling

from jinja2 import Environment

def template_parses(content: str) -> bool:
    try:
        Environment().parse(content)
        return True
    except Exception:
        return False

if not template_parses(manager.prompts[prompt_id].content):
    raise ValueError(f'prompt {prompt_id} has invalid template syntax')

Try / catch

try:
    rendered = manager.render(prompt_id, variables)
except ValueError as e:
    logger.error('render of %s failed: %s', prompt_id, e.__cause__ or e)
    raise

Prevention

When it happens

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

Common situations: 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.

Related errors


AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18). Data as JSON: /api/errors/020cd5e812e79c5a. Report an issue: GitHub.

Appendix: source

Thrown at litellm/integrations/dotprompt/prompt_manager.py:224

        if template is None:
            available_prompts: Final = list(self.prompts.keys())
            version_str: Final = f" (version {version})" if version else ""
            raise KeyError(f"Prompt '{prompt_id}'{version_str} not found. Available prompts: {available_prompts}")

        variables: Final = prompt_variables or {}

        # Validate input variables against schema if defined
        if template.input_schema:
            self._validate_input(variables, template.input_schema)

        try:
            # Create Jinja2 template and render
            jinja_template: Final = self.jinja_env.from_string(template.content)
            rendered: Final = jinja_template.render(**variables)
            return rendered
        except Exception as e:
            raise ValueError(f"Error rendering template '{prompt_id}': {e}")

    def _validate_input(self, variables: dict[str, Any], schema: dict[str, Any]) -> None:
        """Basic validation of input variables against schema."""
        for field_name, field_type in schema.items():
            if field_name in variables:
                value = variables[field_name]
                expected_type = self._get_python_type(field_type)

                if not isinstance(value, expected_type):
                    raise ValueError(
                        f"Invalid type for field '{field_name}': "
                        f"expected {getattr(expected_type, '__name__', str(expected_type))}, got {type(value).__name__}"
                    )

    def _get_python_type(self, schema_type: str) -> type | tuple:
        """Convert schema type string to Python type."""
        type_mapping: Final[dict[str, type | tuple]] = {
            "string": str,

View on GitHub (pinned to 77b7c6c40c)