huggingface/transformers · error · ValueError

Cannot call `update_indexer` on layer {layer_idx} which is a

Error message

Cannot call `update_indexer` on layer {layer_idx} which is a {type(self.layers[layer_idx]).__name__}; it has no indexer key cache (expected a `DynamicIndexedLayer` or `StaticIndexedLayer`).

What it means

Cache.update_indexer() raises ValueError when the target layer has no update_indexer attribute, i.e. it is not an indexed layer (DynamicIndexedLayer / StaticIndexedLayer as used by indexer-based architectures like Kimi K2 / MoonViT-style retrieval attention). The check is duck-typed via hasattr.

Source

Thrown at src/transformers/cache_utils.py:1441

            raise ValueError("Cannot call `update_conv_state` on a non-LinearAttention layer!")
        recurrent_states = self.layers[layer_idx].update_recurrent_state(recurrent_states, state_idx, **kwargs)
        return recurrent_states

    def update_indexer(self, indexer_key_states: torch.Tensor, layer_idx: int) -> torch.Tensor:
        """
        Updates the indexer key cache for layer `layer_idx`.

        Parameters:
            indexer_key_states (`torch.Tensor`):
                The new indexer key states to cache, shape `[batch_size, seq_len, index_head_dim]`.
            layer_idx (`int`):
                The index of the layer to cache the states for.

        Return:
            `torch.Tensor`: The updated indexer key states (full cache).
        """
        if not hasattr(self.layers[layer_idx], "update_indexer"):
            raise ValueError(
                f"Cannot call `update_indexer` on layer {layer_idx} which is a "
                f"{type(self.layers[layer_idx]).__name__}; it has no indexer key cache "
                f"(expected a `DynamicIndexedLayer` or `StaticIndexedLayer`)."
            )
        return self.layers[layer_idx].update_indexer(indexer_key_states)

    def early_initialization(
        self,
        batch_size: int,
        num_heads: int | list[int],
        head_dim: int | list[int],
        dtype: torch.dtype,
        device: torch.device,
    ):
        """
        Initialize all the layers in advance (it's otherwise lazily initialized on the first `update` call).
        This is useful for our `export` recipes, as `export` needs everything in advance.
        """

View on GitHub (pinned to a597f97485)

Solutions

  1. Only call update_indexer on layers that are DynamicIndexedLayer or StaticIndexedLayer
  2. Guard with hasattr(cache.layers[layer_idx], 'update_indexer') before calling
  3. Verify the model config actually declares indexer heads before driving the indexer cache manually

Example fix

# before
cache.update_indexer(key_states, layer_idx=idx)

# after
if hasattr(cache.layers[idx], "update_indexer"):
    cache.update_indexer(key_states, layer_idx=idx)
Defensive patterns

Strategy: type-guard

Validate before calling

if hasattr(cache.layers[layer_idx], "update_indexer"):
    cache.update_indexer(indexer_key_states, layer_idx=layer_idx)

Type guard

def has_indexer_cache(layer) -> bool:
    return hasattr(layer, "update_indexer") and callable(layer.update_indexer)

Prevention

When it happens

Trigger: Calling cache.update_indexer(indexer_key_states, layer_idx=i) where layers[i] is a plain attention or linear attention layer without an indexer key cache.

Common situations: Reusing indexer-cache code from a retrieval-augmented model on a model without indexer support; wrong layer_idx mapping after model surgery or layer pruning.

Related errors


AI-assisted analysis of huggingface/transformers@a597f97485 (2026-08-14). Data as JSON: /api/errors/4ed97f5bce6ecbb3. Report an issue: GitHub.