{"record":{"id":"322e5e669226b41e","repo":"redis/redis-py","slug":"cache-must-implement-cacheinterface","errorCode":null,"errorMessage":"Cache must implement CacheInterface","messagePattern":"Cache must implement CacheInterface","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"redis/connection.py","lineNumber":3035,"sourceCode":"                raise RedisError(\n                    \"Maintenance notifications are not supported with \"\n                    f\"{connection_class}\"\n                )\n            maint_notifications_config = MaintNotificationsConfig(enabled=False)\n\n        self._event_dispatcher = self._connection_kwargs.get(\"event_dispatcher\", None)\n        if self._event_dispatcher is None:\n            self._event_dispatcher = EventDispatcher()\n\n        if connection_kwargs.get(\"cache_config\") or connection_kwargs.get(\"cache\"):\n            if not check_protocol_version(self._connection_kwargs.get(\"protocol\"), 3):\n                raise RedisError(\"Client caching is only supported with RESP version 3\")\n\n            cache = self._connection_kwargs.get(\"cache\")\n\n            if cache is not None:\n                if not isinstance(cache, CacheInterface):\n                    raise ValueError(\"Cache must implement CacheInterface\")\n\n                self.cache = cache\n            else:\n                if self._cache_factory is not None:\n                    self.cache = CacheProxy(self._cache_factory.get_cache())\n                else:\n                    self.cache = CacheFactory(\n                        self._connection_kwargs.get(\"cache_config\")\n                    ).get_cache()\n\n            init_csc_items()\n            register_csc_items_callback(\n                callback=lambda: self.cache.size,\n                pool_name=get_pool_name(self),\n            )\n\n        connection_kwargs.pop(\"cache\", None)\n        connection_kwargs.pop(\"cache_config\", None)","sourceCodeStart":3017,"sourceCodeEnd":3053,"githubUrl":"https://github.com/redis/redis-py/blob/6a6b581b48225afa0b76912d1028c6035baee932/redis/connection.py#L3017-L3053","documentation":"Raised as ValueError by ConnectionPool.__init__ when the cache argument is provided but is not an instance of CacheInterface. redis-py requires a concrete cache object that implements the CacheInterface contract (get/set/delete/flush/etc.) so the invalidation machinery can drive it. Passing a dict, a plain LRUCache from another library, or a half-implemented stub fails this check.","triggerScenarios":"Passing cache={'k': 'v'} or cache=cachetools.LRUCache(...) to ConnectionPool. Providing a custom cache object that does not inherit/implement CacheInterface.","commonSituations":"Assuming any dict-like object works as a cache. Using cache_config (which builds a default cache) vs cache (which must be a CacheInterface) interchangeably. Subclassing without implementing all abstract methods.","solutions":["Pass an object that implements CacheInterface, or use cache_config to have redis-py build a default cache for you.","If you have a custom cache, make the class inherit CacheInterface and implement its abstract methods.","Drop the cache argument and rely on cache_config when you do not need a custom cache implementation."],"exampleFix":"# before\npool = ConnectionPool(protocol=3, cache={'k': 'v'})\n# after\npool = ConnectionPool(protocol=3, cache_config={})  # builds a CacheInterface impl","handlingStrategy":"type-guard","validationCode":"from redis.cache import CacheInterface\n\ndef ensure_cache(cache):\n    if cache is None or isinstance(cache, CacheInterface):\n        return cache\n    raise TypeError('cache must implement CacheInterface; pass cache_config to build a default cache')\n\npool = ConnectionPool(protocol=3, cache=ensure_cache(user_cache))","typeGuard":"from redis.cache import CacheInterface\n\ndef is_valid_cache(cache) -> bool:\n    return cache is None or isinstance(cache, CacheInterface)","tryCatchPattern":"try:\n    pool = ConnectionPool(protocol=3, cache=user_cache)\nexcept ValueError as e:\n    if 'Cache must implement CacheInterface' in str(e):\n        pool = ConnectionPool(protocol=3, cache_config={})  # build a default cache\n    else:\n        raise","preventionTips":["Use cache_config when you don't need a custom cache implementation.","Make custom caches inherit CacheInterface and implement all abstract methods.","Never pass a plain dict or third-party cache object as cache."],"tags":["client-side-caching","validation","configuration"],"backgroundTag":null,"analyzedSha":"6a6b581b48225afa0b76912d1028c6035baee932","analyzedAt":"2026-08-10T12:52:44.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}