From d35eba302f7c4c7c995a2b0ef172d5171d4de13d Mon Sep 17 00:00:00 2001 From: Muhammad Fawaz Date: Wed, 8 Jul 2026 00:00:59 -0700 Subject: [PATCH] [Bugfix] Avoid leaking Pydantic repr in tool_choice error message (#47028) Signed-off-by: muhammadfawaz1 <135441198+muhammadfawaz1@users.noreply.github.com> Co-authored-by: Mahad Durrani <114791389+mahadrehmann@users.noreply.github.com> --- .../openai/chat_completion/test_serving_chat.py | 7 +++++++ vllm/renderers/online_renderer.py | 7 ++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/tests/entrypoints/openai/chat_completion/test_serving_chat.py b/tests/entrypoints/openai/chat_completion/test_serving_chat.py index b43ac31d3dc..25a9451bc2b 100644 --- a/tests/entrypoints/openai/chat_completion/test_serving_chat.py +++ b/tests/entrypoints/openai/chat_completion/test_serving_chat.py @@ -2124,6 +2124,13 @@ async def test_tool_choice_validation_without_parser(): assert isinstance(response_named, ErrorResponse) assert "tool_choice" in response_named.error.message assert "--tool-call-parser" in response_named.error.message + # The function name should appear in a clean, readable form - + # guards against leaking Pydantic's internal repr of the + # ChatCompletionNamedToolChoiceParam/ChatCompletionNamedFunction + # objects directly into the client-facing error message. + assert "get_weather" in response_named.error.message + assert "ChatCompletionNamedFunction" not in response_named.error.message + assert "ChatCompletionNamedToolChoiceParam" not in response_named.error.message @pytest.mark.asyncio diff --git a/vllm/renderers/online_renderer.py b/vllm/renderers/online_renderer.py index 45a3898d4ac..15a4023fcee 100644 --- a/vllm/renderers/online_renderer.py +++ b/vllm/renderers/online_renderer.py @@ -12,6 +12,7 @@ from vllm.entrypoints.chat_utils import ( ConversationMessage, ) from vllm.entrypoints.openai.chat_completion.protocol import ( + ChatCompletionNamedToolChoiceParam, ChatCompletionRequest, ) from vllm.entrypoints.openai.completion.protocol import ( @@ -134,8 +135,12 @@ class OnlineRenderer: ) elif request.tool_choice != "auto": # "required" or named tool requires tool parser + if isinstance(request.tool_choice, ChatCompletionNamedToolChoiceParam): + tool_choice_desc = f'function "{request.tool_choice.function.name}"' + else: + tool_choice_desc = f'"{request.tool_choice}"' return self.create_error_response( - f'tool_choice="{request.tool_choice}" requires ' + f"tool_choice={tool_choice_desc} requires " "--tool-call-parser to be set" )