{"record":{"id":"e4f6bfefd507cba1","repo":"huggingface/transformers","slug":"cannot-call-update-conv-state-on-a-non-linearatt","errorCode":null,"errorMessage":"Cannot call `update_conv_state` on a non-LinearAttention layer!","messagePattern":"Cannot call `update_conv_state` on a non-LinearAttention layer!","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/transformers/cache_utils.py","lineNumber":1401,"sourceCode":"    def update_conv_state(\n        self, conv_states: torch.Tensor, layer_idx: int, state_idx: int = 0, **kwargs\n    ) -> torch.Tensor:\n        \"\"\"\n        Updates the cache with the new `conv_states` for the layer `layer_idx`.\n\n        Parameters:\n            conv_states (`torch.Tensor`):\n                The new conv states to cache.\n            layer_idx (`int`):\n                The index of the layer to cache the states for.\n\n        Return:\n            `torch.Tensor`: The updated conv states.\n        \"\"\"\n        # NOTE: if we slightly break `update` arg order, we could combine this with it, and allow offloading support\n        # out of the box\n        if not isinstance(self.layers[layer_idx], LinearAttentionCacheLayerMixin):\n            raise ValueError(\"Cannot call `update_conv_state` on a non-LinearAttention layer!\")\n        conv_states = self.layers[layer_idx].update_conv_state(conv_states, state_idx, **kwargs)\n        return conv_states\n\n    def update_recurrent_state(\n        self, recurrent_states: torch.Tensor, layer_idx: int, state_idx: int = 0, **kwargs\n    ) -> torch.Tensor:\n        \"\"\"\n        Updates the cache with the new `recurrent_states` for the layer `layer_idx`.\n\n        Parameters:\n            smm_states (`torch.Tensor`):\n                The new ssm states to cache.\n            layer_idx (`int`):\n                The index of the layer to cache the states for.\n\n        Return:\n            `torch.Tensor`: The updated ssm states.\n        \"\"\"","sourceCodeStart":1383,"sourceCodeEnd":1419,"githubUrl":"https://github.com/huggingface/transformers/blob/a597f974857b3d92939971296bc0deb93d33d780/src/transformers/cache_utils.py#L1383-L1419","documentation":"Cache.update_conv_state() raises ValueError when the target layer is not a LinearAttentionCacheLayerMixin. Conv states exist only on linear attention layers (convolutional prefill states in Mamba/linear-attention hybrids); calling the conv-state API on an attention layer is a category error caught by an isinstance check.","triggerScenarios":"Calling cache.update_conv_state(conv_states, layer_idx=i) where self.layers[i] is an attention layer (CacheLayerMixin but not LinearAttentionCacheLayerMixin) — e.g. using a uniform layer_idx mapping over a hybrid model where layer indices do not correspond to linear attention layers.","commonSituations":"Running hybrid models (alternating attention / linear attention) with code that assumes every layer index has conv states; mixing up layer indexing schemes between the cache and the model's layer_types list.","solutions":["Only call update_conv_state for layer indices that correspond to linear attention layers (check config.layer_types)","Let the model's forward call these APIs itself rather than driving cache updates manually","Verify the layer type at runtime: isinstance(cache.layers[idx], LinearAttentionCacheLayerMixin)"],"exampleFix":"# before\ncache.update_conv_state(conv_states, layer_idx=0)  # layer 0 is full_attention\n\n# after\nlinear_idx = next(i for i, t in enumerate(config.layer_types) if t == \"linear_attention\")\ncache.update_conv_state(conv_states, layer_idx=linear_idx)","handlingStrategy":"type-guard","validationCode":"from transformers.cache_utils import LinearAttentionCacheLayerMixin\n\nif isinstance(cache.layers[layer_idx], LinearAttentionCacheLayerMixin):\n    cache.update_conv_state(conv_states, layer_idx=layer_idx)","typeGuard":"from transformers.cache_utils import LinearAttentionCacheLayerMixin\n\ndef supports_conv_state(cache, layer_idx: int) -> bool:\n    return isinstance(cache.layers[layer_idx], LinearAttentionCacheLayerMixin)","tryCatchPattern":"try:\n    cache.update_conv_state(conv_states, layer_idx=idx)\nexcept ValueError as e:\n    if \"non-LinearAttention layer\" in str(e):\n        pass  # expected for attention layers; skip\n    else:\n        raise","preventionTips":["Do not drive conv-state updates manually on hybrid models; let the model's layers do it","Build the linear-attention layer index set from config.layer_types once and index into it"],"tags":["cache","linear-attention","conv-state","layer-type","valueerror"],"backgroundTag":null,"analyzedSha":"a597f974857b3d92939971296bc0deb93d33d780","analyzedAt":"2026-08-14T18:24:08.354Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}