{"record":{"id":"2440382aae3f1ad2","repo":"redis/redis-py","slug":"eviction-policy-should-be-associated-with-valid-ca","errorCode":null,"errorMessage":"Eviction policy should be associated with valid cache.","messagePattern":"Eviction policy should be associated with valid cache\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"redis/cache.py","lineNumber":349,"sourceCode":"        popped_keys = []\n\n        for _ in range(count):\n            popped_entry = self._cache.collection.popitem(last=False)\n            popped_keys.append(popped_entry[0])\n\n        return popped_keys\n\n    def touch(self, cache_key: CacheKey) -> None:\n        self._assert_cache()\n\n        if self._cache.collection.get(cache_key) is None:\n            raise ValueError(\"Given entry does not belong to the cache\")\n\n        self._cache.collection.move_to_end(cache_key)\n\n    def _assert_cache(self):\n        if self.cache is None or not isinstance(self.cache, CacheInterface):\n            raise ValueError(\"Eviction policy should be associated with valid cache.\")\n\n\nclass EvictionPolicy(Enum):\n    LRU = LRUPolicy\n\n\nclass CacheConfig(CacheConfigurationInterface):\n    DEFAULT_CACHE_CLASS = DefaultCache\n    DEFAULT_EVICTION_POLICY = EvictionPolicy.LRU\n    DEFAULT_MAX_SIZE = 10000\n\n    DEFAULT_ALLOW_LIST = [\n        \"BITCOUNT\",\n        \"BITFIELD_RO\",\n        \"BITPOS\",\n        \"EXISTS\",\n        \"GEODIST\",\n        \"GEOHASH\",","sourceCodeStart":331,"sourceCodeEnd":367,"githubUrl":"https://github.com/redis/redis-py/blob/6a6b581b48225afa0b76912d1028c6035baee932/redis/cache.py#L331-L367","documentation":"Raised as ValueError in LRUPolicy._assert_cache (called by evict_next, evict_many, touch) when self.cache is None or is not an instance of CacheInterface. The eviction policy must be bound to a concrete cache before it can operate; without one, popitem/touch have no collection to act on.","triggerScenarios":"Constructing an LRUPolicy and calling evict_next/evict_many/touch before the policy has been assigned to a cache (policy.cache = cache). Also if cache was explicitly set to None. This is typically an internal misconfiguration in CSC setup.","commonSituations":"Using an eviction policy standalone without wiring it to a Cache. A bug in CacheConfig assembly that leaves the policy unbound. Resetting cache to None while the policy still references it.","solutions":["Assign the policy to a cache before use: policy.cache = cache_instance (normally CacheConfig does this).","Construct the cache via CacheConfig so the eviction policy is bound automatically.","Ensure nothing resets eviction_policy.cache to None after setup."],"exampleFix":"# before\npolicy = LRUPolicy()\npolicy.evict_next()  # ValueError: no cache\n# after\npolicy = LRUPolicy()\npolicy.cache = DefaultCache(CacheConfig())\npolicy.evict_next()","handlingStrategy":"validation","validationCode":"if not isinstance(policy.cache, CacheInterface):\n    policy.cache = DefaultCache(CacheConfig())\npolicy.evict_next()","typeGuard":"from redis.cache import CacheInterface\ndef policy_has_cache(policy) -> bool:\n    return isinstance(getattr(policy, \"cache\", None), CacheInterface)","tryCatchPattern":"try:\n    policy.evict_next()\nexcept ValueError as e:\n    if \"valid cache\" in str(e):\n        policy.cache = DefaultCache(CacheConfig())\n    else:\n        raise","preventionTips":["Build caches through CacheConfig so the eviction policy is auto-bound.","Never call eviction methods before assigning policy.cache."],"tags":["cache","eviction","configuration","client-side-caching"],"backgroundTag":null,"analyzedSha":"6a6b581b48225afa0b76912d1028c6035baee932","analyzedAt":"2026-08-10T12:52:44.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}