{"record":{"id":"bc26cdef1212d161","repo":"vllm-project/vllm","slug":"http-request-failed-0","errorCode":null,"errorMessage":"HTTP request failed: {0}","messagePattern":"HTTP request failed: (.+?)","errorType":"exception","errorClass":"BenchError","httpStatus":null,"severity":"error","filePath":"rust/src/bench/src/error.rs","lineNumber":8,"sourceCode":"// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: Copyright contributors to the vLLM project\n\nuse thiserror::Error;\n\n#[derive(Error, Debug)]\npub enum BenchError {\n    #[error(\"HTTP request failed: {0}\")]\n    Http(#[from] reqwest::Error),\n\n    #[error(\"JSON error: {0}\")]\n    Json(#[from] serde_json::Error),\n\n    #[error(\"Tokenizer error: {0}\")]\n    Tokenizer(String),\n\n    /// The server's /tokenize//detokenize endpoint is not usable (4xx status:\n    /// not exposed, or rejected by a gateway such as LLM-d/EPP that returns\n    /// 400 instead of 404). Callers treat this as \"skip verification\", unlike\n    /// `Tokenizer` errors which are genuine failures.\n    #[error(\"tokenize endpoint unavailable: {0}\")]\n    TokenizeUnavailable(String),\n\n    #[error(\"Configuration error: {0}\")]\n    Config(String),\n","sourceCodeStart":1,"sourceCodeEnd":26,"githubUrl":"https://github.com/vllm-project/vllm/blob/c794754062d49a8fdb63ab3c5215b488b865030c/rust/src/bench/src/error.rs#L1-L26","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (lists built independently can drift)\nlocal_offsets = [m.local_offset(b) for b in local_block_ids]\nremote_offsets = [m.remote_offset(b) for b in remote_block_ids[:limit]]\nsizes = [block_size for _ in local_block_ids]\nmerged = connector.merge_contiguous_blocks(local_offsets, remote_offsets, sizes)\n\n// after (build paired in one pass)\ntriples = [\n    (m.local_offset(b), m.remote_offset(r), block_size)\n    for b, r in zip(local_block_ids, remote_block_ids)\n]\nlocal_offsets, remote_offsets, sizes = map(list, zip(*triples))\nassert len(local_offsets) == len(remote_offsets) == len(sizes)\nmerged = connector.merge_contiguous_blocks(local_offsets, remote_offsets, sizes)","handlingStrategy":"validation","validationCode":"def validate_transfer_lists(offsets_local, offsets_remote, sizes):\n    n = len(offsets_local)\n    if not (n == len(offsets_remote) == len(sizes)):\n        raise ValueError(\n            f\"Block transfer lists out of sync: \"\n            f\"local={n} remote={len(offsets_remote)} sizes={len(sizes)}\"\n        )\n    return n\n\n# before calling the connector:\nvalidate_transfer_lists(local_offsets, remote_offsets, sizes)\nconnector.merge_contiguous_blocks(local_offsets, remote_offsets, sizes)","typeGuard":"from typing import TypeGuard\n\ndef are_paired_block_lists(\n    local_block_ids: list[int], remote_block_ids: list[int]\n) -> TypeGuard[tuple[list[int], list[int]]]:\n    return len(local_block_ids) == len(remote_block_ids) and all(\n        isinstance(l, int) and isinstance(r, int)\n        for l, r in zip(local_block_ids, remote_block_ids)\n    )","tryCatchPattern":"try:\n    merged = connector.merge_contiguous_blocks(local_o, remote_o, sizes)\nexcept ValueError as e:\n    if \"lengths mismatch\" in str(e):\n        logger.error(\n            \"Block list drift: local=%d remote=%d sizes=%d\",\n            len(local_o), len(remote_o), len(sizes),\n        )\n    raise  # contract bug: fix the producer, do not silently truncate","preventionTips":["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."],"tags":["moriio","kv-transfer","validation","numpy","vllm"],"backgroundTag":null,"analyzedSha":"c794754062d49a8fdb63ab3c5215b488b865030c","analyzedAt":"2026-08-14T21:17:39.825Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}