[Bugfix] Return HTTP 400 instead of 501 for unknown chat roles in DeepSeek encoders (#53071)
Signed-off-by: JC-ut0 <809602657@qq.com>
JC-ut0 committed
Aug 20, 2026 at 09:23 UTC
38e9cefdefe2e3562ceb6e8decf5101fd6d5c15c
4 files changed
+29
-2
tests/test_request_input_bounds.py
+16
@@ -271,3 +271,19 @@ def test_encode_messages_preserves_small_chat_prompt(encoding_module):
271
"<|begin▁of▁sentence|><|User|>Hello<|Assistant|></think>"
272
"Hi<|end▁of▁sentence|>Again<|end▁of▁sentence|>"
273
)
274
+
275
+
276
+@pytest.mark.parametrize(
277
+ "encoding_module",
278
+ ENCODING_MODULES,
279
+ ids=["deepseek_v32", "deepseek_v4"],
280
+)
281
+def test_encode_messages_unknown_role_raises_value_error(encoding_module):
282
+ # An invalid role (e.g. uppercase "SYSTEM") is a client error and must be
283
+ # raised as ValueError so the OpenAI serving layer maps it to HTTP 400
284
+ # instead of NotImplementedError, which would map to HTTP 501.
285
+ with pytest.raises(ValueError, match="Invalid role: SYSTEM"):
286
+ encoding_module.encode_messages(
287
+ [{"role": "SYSTEM", "content": "Hello"}],
288
+ thinking_mode="chat",
289
+ )
tests/tokenizers_/test_deepseek_v4.py
+11
@@ -113,6 +113,17 @@ def test_deepseek_v4_explicitly_disables_thinking(kwargs):
113
assert prompt == ("<|begin▁of▁sentence|><|User|>Hello<|Assistant|></think>")
114
115
116
+def test_deepseek_v4_unknown_role_raises_value_error():
117
+ # Invalid roles are client errors: they must surface as ValueError
118
+ # (mapped to HTTP 400 by the OpenAI serving layer), not
119
+ # NotImplementedError (mapped to HTTP 501).
120
+ with pytest.raises(ValueError, match="Invalid role: SYSTEM"):
121
+ _tokenizer().apply_chat_template(
122
+ [{"role": "SYSTEM", "content": "Hello"}],
123
+ tokenize=False,
124
+ )
125
+
126
+
127
def test_deepseek_v4_uses_v4_tool_prompt_from_request_tools():
128
tools = [
129
{
vllm/tokenizers/deepseek_v32_encoding.py
+1
-1
@@ -258,7 +258,7 @@ def render_message(
258
tool_calls=tool_calls_content,
259
)
260
else:
261
- raise NotImplementedError(f"Unknown role: {role}")
261
+ raise ValueError(f"Invalid role: {role}")
262
263
return prompt
264
vllm/tokenizers/deepseek_v4_encoding.py
+1
-1
@@ -353,7 +353,7 @@ def render_message(
353
tool_calls=tc_content,
354
)
355
else:
356
- raise NotImplementedError(f"Unknown role: {role}")
356
+ raise ValueError(f"Invalid role: {role}")
357
358
# Append transition tokens based on what follows
359
if index + 1 < len(messages) and messages[index + 1].get("role") not in ["assistant", "latest_reminder"]: