vllm-project/vllm · error · BenchError
HTTP request failed: {0}
Error message
HTTP request failed: {0} What it means
Raised by MoRIIOConnector.merge_contiguous_blocks (moriio_connector.py:2423) when the three parallel lists describing KV block transfers — offsets_local, offsets_remote, sizes — do not all have the same length. The function vectorizes the three lists with np.fromiter(..., count=n) and merges adjacent blocks whose local and remote offsets are both contiguous, so it requires element i of each list to describe the same block. Any caller-supplied mismatch is a programming/contract error, not a runtime condition, and the function refuses to guess an alignment.
Source
Thrown at rust/src/bench/src/error.rs:8
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: Copyright contributors to the vLLM project
use thiserror::Error;
#[derive(Error, Debug)]
pub enum BenchError {
#[error("HTTP request failed: {0}")]
Http(#[from] reqwest::Error),
#[error("JSON error: {0}")]
Json(#[from] serde_json::Error),
#[error("Tokenizer error: {0}")]
Tokenizer(String),
/// The server's /tokenize//detokenize endpoint is not usable (4xx status:
/// not exposed, or rejected by a gateway such as LLM-d/EPP that returns
/// 400 instead of 404). Callers treat this as "skip verification", unlike
/// `Tokenizer` errors which are genuine failures.
#[error("tokenize endpoint unavailable: {0}")]
TokenizeUnavailable(String),
#[error("Configuration error: {0}")]
Config(String),
View on GitHub (pinned to c794754062)
Solutions
- Log len(offsets_local), len(offsets_remote), len(sizes) right before the call to identify which list diverges.
- Check the caller that builds the lists (compute_block_transfer_offsets with local_block_ids/remote_block_ids): confirm the two block-id lists are element-wise paired and were not independently filtered, sliced, or deduped.
- If you wrap merge_contiguous_blocks in a custom merge_fn, audit it for any zip/filter/dedup step that must be applied to all three lists together.
- Guard the pairing at the source: zip(local_block_ids, remote_block_ids) and build all three lists in one loop so they cannot drift.
- If sizes are derivable (fixed block size), compute sizes locally as [block_size] * n instead of passing a separately built list.
Example fix
// before (lists built independently can drift)
local_offsets = [m.local_offset(b) for b in local_block_ids]
remote_offsets = [m.remote_offset(b) for b in remote_block_ids[:limit]]
sizes = [block_size for _ in local_block_ids]
merged = connector.merge_contiguous_blocks(local_offsets, remote_offsets, sizes)
// after (build paired in one pass)
triples = [
(m.local_offset(b), m.remote_offset(r), block_size)
for b, r in zip(local_block_ids, remote_block_ids)
]
local_offsets, remote_offsets, sizes = map(list, zip(*triples))
assert len(local_offsets) == len(remote_offsets) == len(sizes)
merged = connector.merge_contiguous_blocks(local_offsets, remote_offsets, sizes) Defensive patterns
Strategy: validation
Validate before calling
def validate_transfer_lists(offsets_local, offsets_remote, sizes):
n = len(offsets_local)
if not (n == len(offsets_remote) == len(sizes)):
raise ValueError(
f"Block transfer lists out of sync: "
f"local={n} remote={len(offsets_remote)} sizes={len(sizes)}"
)
return n
# before calling the connector:
validate_transfer_lists(local_offsets, remote_offsets, sizes)
connector.merge_contiguous_blocks(local_offsets, remote_offsets, sizes) Type guard
from typing import TypeGuard
def are_paired_block_lists(
local_block_ids: list[int], remote_block_ids: list[int]
) -> TypeGuard[tuple[list[int], list[int]]]:
return len(local_block_ids) == len(remote_block_ids) and all(
isinstance(l, int) and isinstance(r, int)
for l, r in zip(local_block_ids, remote_block_ids)
) Try / catch
try:
merged = connector.merge_contiguous_blocks(local_o, remote_o, sizes)
except ValueError as e:
if "lengths mismatch" in str(e):
logger.error(
"Block list drift: local=%d remote=%d sizes=%d",
len(local_o), len(remote_o), len(sizes),
)
raise # contract bug: fix the producer, do not silently truncate Prevention
- Build local/remote/size lists in a single zip loop over paired block ids so they cannot diverge.
- Never filter, slice, or dedupe one of the three lists independently; apply any transform to the triple together.
- When writing a custom merge_fn for compute_block_transfer_offsets, assert equal lengths as the first statement.
- Treat this error as a fail-fast assertion: a mismatch means upstream bookkeeping is wrong, so do not catch-and-continue in production.
When it happens
Trigger: Calling merge_contiguous_blocks, or _compute_block_transfer_offsets / compute_block_transfer_offsets with a merge_fn that forwards to it (moriio_connector.py:2519), where local_block_ids, remote_block_ids, or the size computation produce lists of different lengths. Concretely: len(local_block_ids) != len(remote_block_ids) passed down from block allocation metadata, or a custom merge_fn/filter step that drops elements from one list (e.g. dedupes offsets_local but not offsets_remote) before calling it. It also fires if any input is a generator/iterator that was partially consumed, since np.fromiter(count=n) with mismatched iteration length raises — but the explicit ValueError here comes from the length check at line 2422.
Common situations: Prefill/decode block id lists diverge because remote_moriio_meta.num_blocks was used to clip remote_block_ids but not local_block_ids; heterogeneous TP setups where kv-head remapping produces a different number of offsets per side; a fork or copy of compute_block_transfer_offsets that appends an extra tail offset; passing zip()-truncated leftovers from earlier processing. Because the only in-repo caller builds the lists itself, hitting this usually means custom code was added between allocation and the merge call.
Related errors
- JSON error: {0}
- Tokenizer error: {0}
- tokenize endpoint unavailable: {0}
- kv_connector_module_path cannot be an empty string.
- Hf3fsClient.check Failed
AI-assisted analysis of vllm-project/vllm@c794754062 (2026-08-14).
Data as JSON: /api/errors/bc26cdef1212d161.
Report an issue: GitHub.