A high-throughput and memory-efficient inference and serving engine for LLMs
Mirrored from https://github.com/tduncan-lum/Nvidia-Optimization-Stack---VLLM.git
Synced Nov 2, 02:15 UTC
[Bugfix] fix crash in postprocess for null tool args (#43862)
Signed-off-by: William-Rom <william.rom@intility.no> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
William Rom committed
Jun 3, 2026 at 07:17 UTC
f0204358d9b811bde5320c037236e97b8fb6199d
2 files changed
+30
-1
tests/entrypoints/test_chat_utils.py
+28
@@ -13,6 +13,8 @@ from vllm.assets.image import ImageAsset
13
from vllm.assets.video import VideoAsset
14
from vllm.config import ModelConfig
15
from vllm.entrypoints.chat_utils import (
16
+ ConversationMessage,
17
+ _postprocess_messages,
18
parse_chat_messages,
19
parse_chat_messages_async,
20
)
@@ -2714,3 +2716,29 @@ async def test_parse_chat_messages_video_vision_chunk_with_uuid_async(
2716
assert conversation == expected_conversation
2717
_assert_mm_data_is_vision_chunk_input(mm_data, 1)
2718
_assert_mm_uuids(mm_uuids, 1, expected_uuids=[video_uuid], modality="vision_chunk")
2719
+
2720
+
2721
+def test_postprocess_messages_null_arguments_string():
2722
+ """arguments="null" must not reach the chat template as Python None.
2723
+
2724
+ json.loads("null") returns None, which causes Jinja2 templates that call
2725
+ tc.arguments.items() to raise 'None' has no attribute 'items'.
2726
+ The function should coerce it to {} instead.
2727
+ """
2728
+ messages: list[ConversationMessage] = [
2729
+ {
2730
+ "role": "assistant",
2731
+ "content": None,
2732
+ "tool_calls": [
2733
+ {
2734
+ "id": "call_1",
2735
+ "type": "function",
2736
+ "function": {"name": "get_current_time", "arguments": "null"},
2737
+ }
2738
+ ],
2739
+ }
2740
+ ]
2741
+ _postprocess_messages(messages)
2742
+ tool_calls = messages[0]["tool_calls"]
2743
+ assert tool_calls is not None
2744
+ assert tool_calls[0]["function"]["arguments"] == {}
vllm/entrypoints/chat_utils.py
+2
-1
@@ -1854,7 +1854,8 @@ def _postprocess_messages(messages: list[ConversationMessage]) -> None:
1854
# if arguments is None or empty string, set to {}
1855
if content := function.get("arguments"):
1856
if not isinstance(content, (dict, list)):
1857
- function["arguments"] = json.loads(content)
1857
+ parsed = json.loads(content)
1858
+ function["arguments"] = parsed if parsed is not None else {}
1859
else:
1860
function["arguments"] = {}
1861