[Bugfix] Return 400 instead of 500 when multimodal data is sent to a text-only model (#48473)
Signed-off-by: Hoang Nguyen Tien <hoang.nguyentien.2601@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Hoang Nguyen committed
Jul 14, 2026 at 15:15 UTC
038ec293b17d8d1018b5494a97187597b10c5182
2 files changed
+32
-2
tests/renderers/test_process_multi_modal_uuids.py
+30
@@ -1,11 +1,14 @@
1
# SPDX-License-Identifier: Apache-2.0
2
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4
+from http import HTTPStatus
5
+
6
import pytest
7
8
from vllm.assets.image import ImageAsset
9
from vllm.assets.video import VideoAsset
10
from vllm.config import CacheConfig, ModelConfig, VllmConfig
11
+from vllm.entrypoints.serve.utils.error_response import create_error_response
12
from vllm.multimodal.parse import parse_mm_uuids
13
from vllm.renderers.hf import HfRenderer
14
from vllm.tokenizers.registry import cached_tokenizer_from_config
@@ -35,6 +38,33 @@ def _build_renderer(
38
)
39
40
41
+def _build_text_only_renderer() -> HfRenderer:
42
+ model_config = ModelConfig(model="openai-community/gpt2", max_model_len=128)
43
+
44
+ return HfRenderer(
45
+ VllmConfig(model_config=model_config),
46
+ cached_tokenizer_from_config(model_config),
47
+ )
48
+
49
+
50
+def test_text_only_model_mm_data_maps_to_bad_request():
51
+ """Sending multimodal data to a text-only model is a client mistake, so it
52
+ must surface as a ValueError and reach the client as HTTP 400, not 500."""
53
+ renderer = _build_text_only_renderer()
54
+
55
+ with pytest.raises(ValueError, match="text-only") as exc_info:
56
+ renderer._process_multimodal(
57
+ prompt="What is in this image?",
58
+ mm_data={"image": [cherry_pil_image]},
59
+ mm_uuids=None,
60
+ mm_processor_kwargs=None,
61
+ tokenization_kwargs=None,
62
+ )
63
+
64
+ error_response = create_error_response(exc_info.value)
65
+ assert error_response.error.code == HTTPStatus.BAD_REQUEST
66
+
67
+
68
def test_multi_modal_uuids_length_mismatch_raises():
69
renderer = _build_renderer()
70
vllm/renderers/base.py
+2
-2
@@ -735,13 +735,13 @@ class BaseRenderer(ABC, Generic[_T]):
735
*,
736
skip_mm_cache: bool = False,
737
) -> "MultiModalInput":
738
- mm_req_id = f"renderer{self.api_process_rank}-mm-{self._mm_req_counter.inc(1)}"
739
-
738
if skip_mm_cache and self._readonly_mm_processor is not None:
739
mm_processor = self._readonly_mm_processor
740
else:
741
mm_processor = self.get_mm_processor()
742
743
+ mm_req_id = f"renderer{self.api_process_rank}-mm-{self._mm_req_counter.inc(1)}"
744
+
745
mm_data_items = mm_processor.info.parse_mm_data(mm_data)
746
mm_uuid_items = parse_mm_uuids(mm_uuids)
747