huggingface/transformers · error · TypeError

One of the two arguments is not a Cache: {type(caches[0]) =

Error message

One of the two arguments is not a Cache: {type(caches[0]) = }, {type(caches[1]) = }

What it means

EncoderDecoderCache.__init__ accepts either one DDP-style iterable or exactly two Cache objects (self-attention cache and cross-attention cache). This TypeError is raised when two positional arguments are passed but at least one of them is not an instance of transformers.cache_utils.Cache (e.g. raw tuples of key/value tensors, a list, or None). The constructor checks isinstance(caches[0], Cache) and isinstance(caches[1], Cache) and refuses anything else.

Source

Thrown at src/transformers/cache_utils.py:1992

        # For dp and ddp support, if only one argument is passed, it should be an iterable of DynamicCache ddp data
        if len(caches) == 1:
            self_attention_cache_data, cross_attention_cache_data = [], []
            for combined_cache_data in caches[0]:
                if len(combined_cache_data) == 6:  # two tuple of style (self_attn_k, self_attn_v, self_attn_sliding)
                    self_attention_cache_data.append(combined_cache_data[:3])
                    cross_attention_cache_data.append(combined_cache_data[3:])
                # To support old DDP-style init, we handle the case where the tuple has no sliding window tensor
                elif len(combined_cache_data) == 4:  # two tuple of style (self_attn_k, self_attn_v)
                    self_attention_cache_data.append(combined_cache_data[:2])
                    cross_attention_cache_data.append(combined_cache_data[2:])
                else:
                    raise ValueError(f"Expected {len(combined_cache_data) = } to be 4 or 6.\n{combined_cache_data = }")
            self.self_attention_cache = DynamicCache(self_attention_cache_data)
            self.cross_attention_cache = DynamicCache(cross_attention_cache_data)
        # Otherwise, we should get two arguments, a self-attention cache and a cross-attention cache
        elif len(caches) == 2:
            if not isinstance(caches[0], Cache) or not isinstance(caches[1], Cache):
                raise TypeError(f"One of the two arguments is not a Cache: {type(caches[0]) = }, {type(caches[1]) = }")
            self.self_attention_cache = caches[0]
            self.cross_attention_cache = caches[1]
        # Error case
        else:
            raise ValueError(f"Expected 1 or 2 arguments, got {len(caches)}")

        self.is_updated = {}
        for layer_idx in range(len(self.cross_attention_cache)):
            self.is_updated[layer_idx] = bool(self.cross_attention_cache.get_seq_length(layer_idx) > 0)

    def __iter__(self):
        """Returns tuples of style (self_attn_k, self_attn_v, self_attn_sliding, cross_attn_k, cross_attn_v, cross_attn_sliding)"""
        for self_attention_layer, cross_attention_layer in zip(self.self_attention_cache, self.cross_attention_cache):
            yield self_attention_layer + cross_attention_layer

    def __repr__(self) -> str:
        return (
            f"{self.__class__.__name__}(self_attention_cache={self.self_attention_cache}, cross_attention_cache="

View on GitHub (pinned to a597f97485)

Solutions

  1. Wrap raw tensors in DynamicCache first: EncoderDecoderCache(DynamicCache(self_kv), DynamicCache(cross_kv))
  2. If you have a single DDP-style iterable of per-layer tuples of length 4 or 6, pass it as the only argument instead of two arguments
  3. Ensure any custom cache class subclasses transformers.cache_utils.Cache
  4. Check that neither argument is None or an already-unpacked tuple before constructing

Example fix

// before
past = EncoderDecoderCache(self_attn_kvs, cross_attn_kvs)  # raw tuples -> TypeError

// after
from transformers import DynamicCache, EncoderDecoderCache
past = EncoderDecoderCache(DynamicCache(self_attn_kvs), DynamicCache(cross_attn_kvs))
Defensive patterns

Strategy: type-guard

Validate before calling

from transformers.cache_utils import Cache
def is_cache_pair_ok(a, b) -> bool:
    return isinstance(a, Cache) and isinstance(b, Cache)

Type guard

from transformers.cache_utils import Cache

def ensure_caches(*caches) -> tuple[Cache, Cache]:
    if len(caches) == 2 and all(isinstance(c, Cache) for c in caches):
        return caches[0], caches[1]
    raise TypeError(f"Need two Cache instances, got {[type(c) for c in caches]}")

Try / catch

try:
    enc_cache = EncoderDecoderCache(self_cache, cross_cache)
except TypeError as e:
    if "not a Cache" in str(e):
        self_cache, cross_cache = DynamicCache(self_kv), DynamicCache(cross_kv)
        enc_cache = EncoderDecoderCache(self_cache, cross_cache)
    else:
        raise

Prevention

When it happens

Trigger: Calling EncoderDecoderCache(past_key_values_tuple, cross_attn_tuple) with plain tuples/lists instead of Cache instances; passing (DynamicCache(), None); passing a dict of key_values; or passing a single cache plus a second unrelated object. Any call with 2 positional args where either fails isinstance(x, Cache).

Common situations: Migrating older code that built past_key_values as tuple-of-tuples and now wraps them in EncoderDecoderCache; using a custom cache class that does not subclass Cache; accidentally passing torch.Tensor key/value stacks; mixing up argument order with a DynamicCache and a StaticCache in a pipeline (valid types) vs a tuple (invalid).

Related errors


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