diff --git a/python/sglang/srt/entrypoints/openai/serving_chat.py b/python/sglang/srt/entrypoints/openai/serving_chat.py index e4fdb4d7f..4b1762ab6 100644 --- a/python/sglang/srt/entrypoints/openai/serving_chat.py +++ b/python/sglang/srt/entrypoints/openai/serving_chat.py @@ -7,6 +7,7 @@ import time import uuid from typing import TYPE_CHECKING, Any, AsyncGenerator, Dict, List, Optional, Union +import jinja2 import orjson from fastapi import Request from fastapi.responses import ORJSONResponse, StreamingResponse @@ -362,27 +363,32 @@ class OpenAIServingChat(OpenAIServingBase): else {} ), ) - except Exception: - # This except branch will be triggered when the chosen model - # has a different tools input format that is not compatible - # with openAI's apply_chat_template tool_call format, like Mistral. + except Exception as e: + # If the first attempt fails, try transforming the tools format + # This handles models like Mistral that have a different tools input format + # that is not compatible with OpenAI's apply_chat_template tool_call format tools = ( [t if "function" in t else {"function": t} for t in tools] if tools else None ) - prompt_ids = self.tokenizer_manager.tokenizer.apply_chat_template( - openai_compatible_messages, - tokenize=True, - add_generation_prompt=True, - tools=tools, - reasoning_effort=request.reasoning_effort, - **( - request.chat_template_kwargs - if request.chat_template_kwargs - else {} - ), - ) + try: + prompt_ids = self.tokenizer_manager.tokenizer.apply_chat_template( + openai_compatible_messages, + tokenize=True, + add_generation_prompt=True, + tools=tools, + reasoning_effort=request.reasoning_effort, + **( + request.chat_template_kwargs + if request.chat_template_kwargs + else {} + ), + ) + except jinja2.TemplateError as template_error: + # Template errors (e.g., from raise_exception in Jinja templates) + # should be treated as client errors (400 BadRequest) + raise ValueError(str(template_error)) from template_error if assistant_prefix: encoded = self.tokenizer_manager.tokenizer.encode(assistant_prefix)