{"record":{"id":"5496fc932aeac7c1","repo":"BerriAI/litellm","slug":"error-rendering-template-e","errorCode":null,"errorMessage":"Error rendering template - {e}","messagePattern":"Error rendering template - (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"litellm/litellm_core_utils/prompt_templates/factory.py","lineNumber":441,"sourceCode":"                    add_generation_prompt=True,\n                )\n            except Exception as e:\n                if \"Conversation roles must alternate user/assistant\" in str(e):\n                    # reformat messages to ensure user/assistant are alternating\n                    new_messages: Final = []\n                    for i in range(len(reformatted_messages) - 1):\n                        new_messages.append(reformatted_messages[i])\n                        if reformatted_messages[i][\"role\"] == reformatted_messages[i + 1][\"role\"]:\n                            if reformatted_messages[i][\"role\"] == \"user\":\n                                new_messages.append({\"role\": \"assistant\", \"content\": \"\"})\n                            else:\n                                new_messages.append({\"role\": \"user\", \"content\": \"\"})\n                    new_messages.append(reformatted_messages[-1])\n                    rendered_text = template.render(bos_token=bos_token, eos_token=eos_token, messages=new_messages)\n\n        return rendered_text\n    except Exception as e:\n        raise Exception(f\"Error rendering template - {e}\")  # don't use verbose_logger.exception, if exception is raised\n\n\nasync def _afetch_and_extract_template(\n    model: str, chat_template: Any | None, get_config_fn, get_template_fn\n) -> tuple[str, str, str]:\n    \"\"\"\n    Async version: Fetch template and tokens from HuggingFace.\n\n    Returns: (chat_template, bos_token, eos_token)\n    \"\"\"\n    from litellm.litellm_core_utils.prompt_templates.huggingface_template_handler import (\n        _extract_token_value,\n    )\n\n    bos_token = \"\"\n    eos_token = \"\"\n\n    if chat_template is None:","sourceCodeStart":423,"sourceCodeEnd":459,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/litellm_core_utils/prompt_templates/factory.py#L423-L459","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Read the embedded Jinja2 error: a name like 'message.tool_calls is undefined' tells you exactly what message shape the template needs","Pass an explicit, known-good chat_template=... parameter (or chat_template_file) instead of relying on the repo's template","Simplify messages to plain user/assistant strings to confirm the template works, then add complexity back","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"],"exampleFix":"# before\nresp = litellm.completion(\n    model=\"huggingface/mistralai/Mistral-7B-Instruct-v0.1\",\n    messages=[{\"role\": \"system\", \"content\": \"You are...\"}],\n)  # repo template fails on system role\n\n# after\nresp = litellm.completion(\n    model=\"huggingface/mistralai/Mistral-7B-Instruct-v0.1\",\n    messages=[{\"role\": \"user\", \"content\": \"Hi\"}],\n    chat_template=\"{% for message in messages %}{{ '<s>' + message['content'] + '</s>' }}{% endfor %}\",\n)","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    resp = litellm.completion(model=\"huggingface/...\", messages=messages, chat_template=chat_template)\nexcept Exception as e:\n    if \"Error rendering template\" in str(e):\n        # fall back to a minimal known-good template with plain user/assistant turns\n        simple = [{\"role\": m[\"role\"], \"content\": str(m.get(\"content\", \"\"))}\n                  for m in messages if m[\"role\"] in (\"user\", \"assistant\")]\n        resp = litellm.completion(\n            model=\"huggingface/...\", messages=simple,\n            chat_template=\"{% for m in messages %}{{ m['content'] }}{% endfor %}\",\n        )\n    else:\n        raise","preventionTips":["Test custom chat_template strings with Jinja2 directly before using them","Keep messages to the roles/fields your template documents","Pin model revisions whose templates you have verified"],"tags":["huggingface","jinja2","chat-template","rendering"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}