vllm - 💡(How to fix) Fix [Bug]: `--num-gpu-blocks-override 0` silently accepted; engine init fails with bare `AssertionError` in `BlockPool.__init__` [2 pull requests]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

--num-gpu-blocks-override 0 (and any non-positive value) passes through CacheConfig without validation. The override then replaces the profiled num_gpu_blocks, and BlockPool.__init__ fails with a bare AssertionError (no message) at vllm/v1/core/block_pool.py:157.

This is the same class of UX defect as #43496 / #43521 / #43532 (all recently closed by #43794), and has the same one-line fix shape.

Error Message

from unittest.mock import MagicMock from vllm.config.cache import CacheConfig from vllm.v1.core.kv_cache_utils import may_override_num_blocks from vllm.v1.core.block_pool import BlockPool

Step 1 — CacheConfig silently accepts 0 (and -1).

assert CacheConfig(num_gpu_blocks_override=0).num_gpu_blocks_override == 0 assert CacheConfig(num_gpu_blocks_override=-1).num_gpu_blocks_override == -1

Step 2 — the override replaces a positive profiled num_blocks.

vllm_cfg = MagicMock() vllm_cfg.cache_config = CacheConfig(num_gpu_blocks_override=0) assert may_override_num_blocks(vllm_cfg, num_blocks=4096) == 0

Step 3 — BlockPool asserts, with no useful message.

BlockPool(num_gpu_blocks=0, enable_caching=False, hash_block_size=16)

AssertionError Traceback (most recent call last)

File "vllm/v1/core/block_pool.py", line 157, in init

assert isinstance(num_gpu_blocks, int) and num_gpu_blocks > 0

AssertionError

Root Cause

--num-gpu-blocks-override 0 (and any non-positive value) passes through CacheConfig without validation. The override then replaces the profiled num_gpu_blocks, and BlockPool.__init__ fails with a bare AssertionError (no message) at vllm/v1/core/block_pool.py:157.

This is the same class of UX defect as #43496 / #43521 / #43532 (all recently closed by #43794), and has the same one-line fix shape.

Fix Action

Fixed

Code Example

from unittest.mock import MagicMock
from vllm.config.cache import CacheConfig
from vllm.v1.core.kv_cache_utils import may_override_num_blocks
from vllm.v1.core.block_pool import BlockPool

# Step 1CacheConfig silently accepts 0 (and -1).
assert CacheConfig(num_gpu_blocks_override=0).num_gpu_blocks_override == 0
assert CacheConfig(num_gpu_blocks_override=-1).num_gpu_blocks_override == -1

# Step 2 — the override replaces a positive profiled num_blocks.
vllm_cfg = MagicMock()
vllm_cfg.cache_config = CacheConfig(num_gpu_blocks_override=0)
assert may_override_num_blocks(vllm_cfg, num_blocks=4096) == 0

# Step 3BlockPool asserts, with no useful message.
BlockPool(num_gpu_blocks=0, enable_caching=False, hash_block_size=16)
# AssertionError                            Traceback (most recent call last)
#   File "vllm/v1/core/block_pool.py", line 157, in __init__
#     assert isinstance(num_gpu_blocks, int) and num_gpu_blocks > 0
# AssertionError

---

ValueError: 1 validation error for CacheConfig
num_gpu_blocks_override
  Input should be greater than 0 [type=greater_than, input_value=0, ...]

---

- num_gpu_blocks_override: int | None = None
+ num_gpu_blocks_override: int | None = Field(default=None, gt=0)
RAW_BUFFERClick to expand / collapse

Summary

--num-gpu-blocks-override 0 (and any non-positive value) passes through CacheConfig without validation. The override then replaces the profiled num_gpu_blocks, and BlockPool.__init__ fails with a bare AssertionError (no message) at vllm/v1/core/block_pool.py:157.

This is the same class of UX defect as #43496 / #43521 / #43532 (all recently closed by #43794), and has the same one-line fix shape.

Repro (against current main, commit 6cc8577 at time of filing)

from unittest.mock import MagicMock
from vllm.config.cache import CacheConfig
from vllm.v1.core.kv_cache_utils import may_override_num_blocks
from vllm.v1.core.block_pool import BlockPool

# Step 1 — CacheConfig silently accepts 0 (and -1).
assert CacheConfig(num_gpu_blocks_override=0).num_gpu_blocks_override == 0
assert CacheConfig(num_gpu_blocks_override=-1).num_gpu_blocks_override == -1

# Step 2 — the override replaces a positive profiled num_blocks.
vllm_cfg = MagicMock()
vllm_cfg.cache_config = CacheConfig(num_gpu_blocks_override=0)
assert may_override_num_blocks(vllm_cfg, num_blocks=4096) == 0

# Step 3 — BlockPool asserts, with no useful message.
BlockPool(num_gpu_blocks=0, enable_caching=False, hash_block_size=16)
# AssertionError                            Traceback (most recent call last)
#   File "vllm/v1/core/block_pool.py", line 157, in __init__
#     assert isinstance(num_gpu_blocks, int) and num_gpu_blocks > 0
# AssertionError

Expected

A clean ValueError at config construction (matching the pattern from #43794), e.g.

ValueError: 1 validation error for CacheConfig
num_gpu_blocks_override
  Input should be greater than 0 [type=greater_than, input_value=0, ...]

Proposed fix

Mirror the field-level shape #43794 landed for block_size and hash_block_size. In vllm/config/cache.py:

- num_gpu_blocks_override: int | None = None
+ num_gpu_blocks_override: int | None = Field(default=None, gt=0)

(The int | None Union keeps the existing "no override" default working; gt=0 rejects 0 and any negative integer at construction time.)

Alternatively, replace the bare assert at block_pool.py:157 with a descriptive raise ValueError(...) — but that only improves the diagnostic; it doesn't prevent the engine from getting that far.

Discovery context

Static finding from the broader CLI-int-fields audit in lucasccordeiro/vllm AUDIT.md Finding #4; ESBMC counterexample in harness/num_gpu_blocks_override_zero_cli_path.py. The witness is user_override=0, profiled=1 → num_blocks=0 → assert num_blocks > 0 fires.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING