{"record":{"id":"eeff36103b045946","repo":"huggingface/transformers","slug":"passing-a-tuple-of-past-key-values-is-not-suppor","errorCode":null,"errorMessage":"Passing a tuple of `past_key_values` is not supported anymore. Please use a `Cache` instance.","messagePattern":"Passing a tuple of `past_key_values` is not supported anymore\\. Please use a `Cache` instance\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/transformers/generation/utils.py","lineNumber":1955,"sourceCode":"        \"\"\"\n        Prepares the cache for generation (if applicable), given `generate`'s parameterization. If a cache is\n        instantiated, writes it to `model_kwargs`, under the name expected by the model.\n        \"\"\"\n\n        # TODO @raushan, unify cache arg naming for all models\n        is_linear_attn_cache = \"mamba\" in self.__class__.__name__.lower()\n        cache_name = \"past_key_values\" if not is_linear_attn_cache else \"cache_params\"\n\n        # Quick escape route 1: if the user specifies a cache, we only need to check for conflicting `generate` arguments\n        user_defined_cache = model_kwargs.get(cache_name)\n        if user_defined_cache is not None:\n            if generation_config.cache_implementation is not None:\n                raise ValueError(\n                    f\"Passing both `cache_implementation` (used to initialize certain caches) and `{cache_name}` (a \"\n                    \"Cache object) is unsupported. Please use only one of the two.\"\n                )\n            if isinstance(user_defined_cache, tuple):\n                raise ValueError(\n                    \"Passing a tuple of `past_key_values` is not supported anymore. Please use a `Cache` instance.\"\n                )\n            return\n\n        # Quick escape route 2: if the user specifies no cache is to be used. (conflicting arguments are handled in\n        # `generation_config.validate()`)\n        if generation_config.use_cache is False:\n            return\n\n        # Quick escape route 3: model that supply it in `prepare_inputs_for_generation` (mamba, zamba, ...)\n        if not self._supports_default_dynamic_cache():\n            if generation_config.cache_implementation is not None:\n                logger.warning_once(\n                    \"This model does not support `Cache` instances. `cache_implementation` (set to \"\n                    f\"{generation_config.cache_implementation}) will be ignored.\",\n                )\n            return\n","sourceCodeStart":1937,"sourceCodeEnd":1973,"githubUrl":"https://github.com/huggingface/transformers/blob/a597f974857b3d92939971296bc0deb93d33d780/src/transformers/generation/utils.py#L1937-L1973","documentation":"Legacy transformers returned/accepted the cache as a tuple of `(key_states, value_states)` per layer. Modern generation requires the object-oriented `Cache` API (e.g. `DynamicCache`) which supports in-place updates and arbitrary cache layouts. If the value passed under `past_key_values` (or `cache_params`) is a tuple, generate raises.","triggerScenarios":"`model.generate(**inputs, past_key_values=legacy_tuple)`; passing a manually built `tuple` of per-layer key/value tensors; forwarding cache output captured from an old transformers version or legacy code path.","commonSituations":"Code written for transformers < 4.36 after an upgrade; caches serialized to disk in tuple form; manual prompt-prefilling code that constructs tuples; copies of old StackOverflow snippets.","solutions":["Use a `Cache` instance: `from transformers import DynamicCache; out = model.generate(**inputs, past_key_values=DynamicCache())`.","Convert an existing tuple: `cache = DynamicCache.from_legacy_cache(legacy_tuple)`.","Stop capturing/serializing caches as tuples; persist `DynamicCache` state instead.","If a third-party library hands you tuples, wrap its output with `DynamicCache.from_legacy_cache` at the boundary."],"exampleFix":"# before\nout = model.generate(**inputs, past_key_values=old_tuple_cache)  # ValueError: tuple not supported\n\n# after\nfrom transformers import DynamicCache\nout = model.generate(**inputs, past_key_values=DynamicCache.from_legacy_cache(old_tuple_cache))","handlingStrategy":"type-guard","validationCode":"from transformers import DynamicCache\nif isinstance(past_key_values, tuple):\n    past_key_values = DynamicCache.from_legacy_cache(past_key_values)","typeGuard":"def is_modern_cache(obj) -> bool:\n    return obj is None or not isinstance(obj, tuple)  # Cache instances pass; legacy tuples fail","tryCatchPattern":null,"preventionTips":["Construct caches via DynamicCache()/StaticCache(), never tuples.","Convert at boundaries: DynamicCache.from_legacy_cache(tuple) when interfacing with legacy code.","Don't serialize caches as tuples; store Cache objects or re-encode prompts instead."],"tags":["generation","cache","past-key-values","legacy-migration","breaking-change"],"backgroundTag":null,"analyzedSha":"a597f974857b3d92939971296bc0deb93d33d780","analyzedAt":"2026-08-14T18:24:08.354Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}