[Bugfix] Validate extension integers before engine serialization (#55606)
Signed-off-by: khluu <khluu000@gmail.com> Co-authored-by: Codex <noreply@openai.com>
Kevin H. Luu committed
Sep 8, 2026 at 01:30 UTC
5db652225f00b55783823ae6606d36925e3e3efe
2 files changed
+44
tests/test_sampling_params.py
+22
@@ -49,3 +49,25 @@ def test_diffusion_accepts_top_k_top_p():
49
def test_non_diffusion_models_unaffected():
50
params = SamplingParams(temperature=0.7, top_k=10, seed=42)
51
params.verify(MockModelConfig(), None, None, None)
52
+
53
+
54
+@pytest.mark.parametrize("value", [-(2**63) - 1, 2**64])
55
+def test_extra_args_rejects_nested_integer_overflow(value):
56
+ """Reject extension values before they reach the engine transport."""
57
+ with pytest.raises(VLLMValidationError, match="extra_args integers"):
58
+ SamplingParams(extra_args={"ec_transfer_params": {"nested": [{"x": value}]}})
59
+
60
+
61
+@pytest.mark.parametrize("value", [-(2**63), 2**63 - 1, 2**63, 2**64 - 1, True])
62
+def test_extra_args_accepts_messagepack_integer_boundaries(value):
63
+ extra_args = {"kv_transfer_params": {"nested": [{"x": value}]}}
64
+ assert SamplingParams(extra_args=extra_args).extra_args == extra_args
65
+
66
+
67
+def test_extra_args_preserves_custom_objects_and_shared_containers():
68
+ custom = object()
69
+ shared = [custom, (None, "value", 1.5)]
70
+ extra_args = {"first": shared, "second": shared}
71
+ params = SamplingParams(extra_args=extra_args)
72
+ assert params.extra_args["first"][0] is custom
73
+ assert params.extra_args["first"] is params.extra_args["second"]
vllm/sampling_params.py
+22
@@ -544,6 +544,8 @@ class SamplingParams(
544
545
def _verify_args(self) -> None:
546
_verify_num_sequences(self.n, "n")
547
+ if self.extra_args:
548
+ self._verify_extra_args()
549
if not -2.0 <= self.presence_penalty <= 2.0:
550
raise VLLMValidationError(
551
f"presence_penalty must be in [-2, 2], got {self.presence_penalty}."
@@ -655,6 +657,26 @@ class SamplingParams(
657
f"Got bad_words={self.bad_words}"
658
)
659
660
+ def _verify_extra_args(self) -> None:
661
+ # JSON accepts arbitrary integers, but the engine's MessagePack
662
+ # transport only supports signed/unsigned 64-bit integers.
663
+ pending: list[Any] = [self.extra_args]
664
+ visited: set[int] = set()
665
+ while pending:
666
+ value = pending.pop()
667
+ if isinstance(value, int) and not -(2**63) <= value < 2**64:
668
+ raise VLLMValidationError(
669
+ "extra_args integers must be between -2**63 and 2**64 - 1.",
670
+ parameter="extra_args",
671
+ )
672
+ if isinstance(value, (dict, list, tuple)) and id(value) not in visited:
673
+ visited.add(id(value))
674
+ if isinstance(value, dict):
675
+ pending.extend(value.keys())
676
+ pending.extend(value.values())
677
+ else:
678
+ pending.extend(value)
679
+
680
def _verify_greedy_sampling(self) -> None:
681
if self.n > 1:
682
raise VLLMValidationError(