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
- Wrap raw tensors in DynamicCache first: EncoderDecoderCache(DynamicCache(self_kv), DynamicCache(cross_kv))
- 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
- Ensure any custom cache class subclasses transformers.cache_utils.Cache
- 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
- Always construct inner caches with DynamicCache/StaticCache constructors, never raw tensors
- Assert isinstance(x, Cache) before composing EncoderDecoderCache
- Keep a helper that builds EncoderDecoderCache from tensors so wrapping is never forgotten
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
- Expected 1 or 2 arguments, got {len(caches)}
- `{method}` is only defined for dynamic cache, got {self.self
- You can construct a Cache either from a list `layers` of all
- You should provide exactly one of `layers` or `layer_class_t
- Expected {len(combined_cache_data) = } to be 4 or 6. {combin
AI-assisted analysis of huggingface/transformers@a597f97485 (2026-08-14).
Data as JSON: /api/errors/ed9d2363ee40e230.
Report an issue: GitHub.