BerriAI/litellm · error · Exception

Error rendering template - {e}

Error message

Error rendering template - {e}

What it means

This Exception wraps any failure while rendering a HuggingFace tokenizer chat template (Jinja2) over your messages. The template was found but template.render(bos_token=..., eos_token=..., messages=...) raised — usually because the template references fields your messages lack, or the custom chat_template string is invalid Jinja2. The underlying error text is embedded in the message.

Source

Thrown at litellm/litellm_core_utils/prompt_templates/factory.py:441

                    add_generation_prompt=True,
                )
            except Exception as e:
                if "Conversation roles must alternate user/assistant" in str(e):
                    # reformat messages to ensure user/assistant are alternating
                    new_messages: Final = []
                    for i in range(len(reformatted_messages) - 1):
                        new_messages.append(reformatted_messages[i])
                        if reformatted_messages[i]["role"] == reformatted_messages[i + 1]["role"]:
                            if reformatted_messages[i]["role"] == "user":
                                new_messages.append({"role": "assistant", "content": ""})
                            else:
                                new_messages.append({"role": "user", "content": ""})
                    new_messages.append(reformatted_messages[-1])
                    rendered_text = template.render(bos_token=bos_token, eos_token=eos_token, messages=new_messages)

        return rendered_text
    except Exception as e:
        raise Exception(f"Error rendering template - {e}")  # don't use verbose_logger.exception, if exception is raised


async def _afetch_and_extract_template(
    model: str, chat_template: Any | None, get_config_fn, get_template_fn
) -> tuple[str, str, str]:
    """
    Async version: Fetch template and tokens from HuggingFace.

    Returns: (chat_template, bos_token, eos_token)
    """
    from litellm.litellm_core_utils.prompt_templates.huggingface_template_handler import (
        _extract_token_value,
    )

    bos_token = ""
    eos_token = ""

    if chat_template is None:

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Read the embedded Jinja2 error: a name like 'message.tool_calls is undefined' tells you exactly what message shape the template needs
  2. Pass an explicit, known-good chat_template=... parameter (or chat_template_file) instead of relying on the repo's template
  3. Simplify messages to plain user/assistant strings to confirm the template works, then add complexity back
  4. If the repo template is broken, pin a revision of the model that has a working template or switch to a model with a maintained template

Example fix

# before
resp = litellm.completion(
    model="huggingface/mistralai/Mistral-7B-Instruct-v0.1",
    messages=[{"role": "system", "content": "You are..."}],
)  # repo template fails on system role

# after
resp = litellm.completion(
    model="huggingface/mistralai/Mistral-7B-Instruct-v0.1",
    messages=[{"role": "user", "content": "Hi"}],
    chat_template="{% for message in messages %}{{ '<s>' + message['content'] + '</s>' }}{% endfor %}",
)
Defensive patterns

Strategy: try-catch

Try / catch

try:
    resp = litellm.completion(model="huggingface/...", messages=messages, chat_template=chat_template)
except Exception as e:
    if "Error rendering template" in str(e):
        # fall back to a minimal known-good template with plain user/assistant turns
        simple = [{"role": m["role"], "content": str(m.get("content", ""))}
                  for m in messages if m["role"] in ("user", "assistant")]
        resp = litellm.completion(
            model="huggingface/...", messages=simple,
            chat_template="{% for m in messages %}{{ m['content'] }}{% endfor %}",
        )
    else:
        raise

Prevention

When it happens

Trigger: Calling completion() on a HuggingFace/Ollama-style model where the repo's chat template expects keys like 'system' or 'tool_calls' but your messages don't supply them in the expected shape; passing api_base/chat_template with a malformed template; message dicts with unexpected types that the Jinja2 template chokes on.

Common situations: Custom fine-tuned models with hand-edited tokenizer_config.json chat templates; upgrading a model repo whose template syntax changed; sending tool messages to a model whose template has no tools support; typos in a user-supplied chat_template parameter.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/5496fc932aeac7c1. Report an issue: GitHub.