{"record":{"id":"d66172781ba25644","repo":"sgl-project/sglang","slug":"layer-id-layer-id-does-not-have-an-index-v-cache","errorCode":null,"errorMessage":"layer_id={layer_id} does not have an index V cache (either dense, or in the K-only group). index_kv layers: {list(self.index_kv_layer_id_mapping.keys())}","messagePattern":"layer_id=(.+?) does not have an index V cache \\(either dense, or in the K-only group\\)\\. index_kv layers: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/mem_cache/memory_pool.py","lineNumber":4958,"sourceCode":"            self.layer_transfer_counter.wait_until(layer_id - self.start_layer)\n\n    def get_key_buffer(self, layer_id: int) -> torch.Tensor:\n        self._wait_for_layer(layer_id)\n        return self.main_pool.get_key_buffer(layer_id)\n\n    def get_value_buffer(self, layer_id: int) -> torch.Tensor:\n        self._wait_for_layer(layer_id)\n        return self.main_pool.get_value_buffer(layer_id)\n\n    def get_kv_buffer(self, layer_id: int) -> Tuple[torch.Tensor, torch.Tensor]:\n        self._wait_for_layer(layer_id)\n        return self.main_pool.get_kv_buffer(layer_id)\n\n    def get_index_kv_buffer(self, layer_id: int) -> Tuple[torch.Tensor, torch.Tensor]:\n        self._wait_for_layer(layer_id)\n        mapped_id = self.index_kv_layer_id_mapping.get(layer_id)\n        if mapped_id is None:\n            raise ValueError(\n                f\"layer_id={layer_id} does not have an index V cache \"\n                f\"(either dense, or in the K-only group). \"\n                f\"index_kv layers: {list(self.index_kv_layer_id_mapping.keys())}\"\n            )\n        return self.index_kv_pool.get_kv_buffer(mapped_id)\n\n    def get_index_k_buffer(self, layer_id: int) -> torch.Tensor:\n        self._wait_for_layer(layer_id)\n        # First try the K-only pool; fall back to the index_kv pool's K side\n        # so callers that just need K work for both sparse subgroups.\n        mapped_id = self.index_k_layer_id_mapping.get(layer_id)\n        if mapped_id is not None:\n            return self.index_k_pool.get_key_buffer(mapped_id)\n        mapped_id = self.index_kv_layer_id_mapping.get(layer_id)\n        if mapped_id is not None:\n            return self.index_kv_pool.get_key_buffer(mapped_id)\n        raise ValueError(\n            f\"layer_id={layer_id} is not a sparse attention layer; \"","sourceCodeStart":4940,"sourceCodeEnd":4976,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/mem_cache/memory_pool.py#L4940-L4976","documentation":"MiniMaxSparseKVPool.get_index_kv_buffer only serves layers registered in index_kv_layer_id_mapping (sparse layers that keep both an index K and an index V cache). The requested layer_id is either a dense layer or a K-only sparse layer, so there is no index-V cache to return.","triggerScenarios":"Calling get_index_kv_buffer(layer_id) where layer_id maps to None in index_kv_layer_id_mapping — e.g. passing a dense attention layer id or a K-only group layer id.","commonSituations":"Custom backends iterating all layers with the index-KV accessor; mismatch between the model's sparse layer partition (K-only vs K+V) and caller assumptions; misconfigured sparse layer lists in the model config.","solutions":["Log list(self.index_kv_layer_id_mapping.keys()) and only call this API for those layer ids","For dense layers use main_pool.get_kv_buffer; for K-only layers use get_key_buffer","Fix the model config / pool construction so the layer is registered as index-KV if it should carry a V cache"],"exampleFix":"// before\nk, v = sparse_pool.get_index_kv_buffer(layer_id)  # dense or K-only layer\n// after\nif layer_id in sparse_pool.index_kv_layer_id_mapping:\n    k, v = sparse_pool.get_index_kv_buffer(layer_id)\nelse:\n    k, v = sparse_pool.main_pool.get_kv_buffer(layer_id)","handlingStrategy":"validation","validationCode":"if layer_id not in sparse_pool.index_kv_layer_id_mapping:\n    raise ValueError(f'{layer_id} has no index-V cache; use main_pool.get_kv_buffer')","typeGuard":"def is_index_kv_layer(sparse_pool, layer_id: int) -> bool:\n    return sparse_pool.index_kv_layer_id_mapping.get(layer_id) is not None","tryCatchPattern":null,"preventionTips":["Build per-group layer lists once and iterate each with the matching accessor","Log the mapping keys at startup for debugging"],"tags":["kv-cache","sparse-attention","layer-id","mapping","minimax","sglang"],"backgroundTag":"invalid-layer-id-mapping","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}