{"record":{"id":"decbf14e120858b3","repo":"BerriAI/litellm","slug":"redis-client-cannot-set-cache-attribute-not-found","errorCode":null,"errorMessage":"Redis client cannot set cache. Attribute not found.","messagePattern":"Redis client cannot set cache\\. Attribute not found\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"litellm/caching/redis_cache.py","lineNumber":713,"sourceCode":"                    call_type=f\"async_set_cache <- {_get_call_stack_info()}\",\n                )\n            )\n            verbose_logger.error(\n                \"LiteLLM Redis Caching: async set() - Got exception from REDIS %s, key=%r, value=%r\",\n                str(e),\n                key,\n                value,\n            )\n            raise e\n\n        key = self.check_and_fix_namespace(key=key)\n        ttl: Final = self.get_ttl(**kwargs)\n        nx: Final = kwargs.get(\"nx\", False)\n        print_verbose(f\"Set ASYNC Redis Cache: key: {key}\\nValue {value}\\nttl={ttl}\")\n\n        try:\n            if not hasattr(_redis_client, \"set\"):\n                raise Exception(\"Redis client cannot set cache. Attribute not found.\")\n            result: Final = await _redis_client.set(\n                name=key,\n                value=json.dumps(value),\n                nx=nx,\n                ex=ttl,\n            )\n            print_verbose(f\"Successfully Set ASYNC Redis Cache: key: {key}\\nValue {value}\\nttl={ttl}\")\n            end_time = time.time()\n            _duration = end_time - start_time\n            asyncio.create_task(\n                self.service_logger_obj.async_service_success_hook(\n                    service=ServiceTypes.REDIS,\n                    duration=_duration,\n                    call_type=f\"async_set_cache <- {_get_call_stack_info()}\",\n                    start_time=start_time,\n                    end_time=end_time,\n                    parent_otel_span=_get_parent_otel_span_from_kwargs(kwargs),\n                    event_metadata={\"key\": key},","sourceCodeStart":695,"sourceCodeEnd":731,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/caching/redis_cache.py#L695-L731","documentation":"Before writing a value, async_set_cache checks that the resolved async Redis client object has a .set method; if it does not, the cached write cannot proceed and an exception is raised. The client resolution path (init_async_client) returned something that is not a functional Redis client — typically an old redis-py version, a patched/mocked object, or a misconfigured client factory.","triggerScenarios":"Calling litellm.acompletion(..., cache={'redis...': ...}) or await cache.async_set_cache(...) where the constructed async client lacks .set; commonly after injecting a mock client in tests or running with a stale redis-py install.","commonSituations":"Unit tests monkeypatching the Redis client with a limited stub; dependency downgrades breaking redis.asyncio.Redis; wrapping the client in an object that delegates but misses .set.","solutions":["Upgrade redis-py to a current version: pip install -U 'redis>=5'","If you pass a custom async client to RedisCache, make sure it delegates .set (and the other standard commands)","In tests, replace the stub with fakeredis.aioredis.FakeRedis"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"def assert_cache_ready(cache) -> None:\n    client = getattr(cache, 'async_client', None) or cache.init_async_client()\n    for op in ('set', 'get', 'delete'):\n        if not hasattr(client, op):\n            raise RuntimeError(f'Async redis client missing .{op}; upgrade redis-py (>=5) or fix injected client')","typeGuard":"def is_functional_async_redis(client: Any) -> TypeGuard[Any]:\n    return all(hasattr(client, m) for m in ('set', 'get', 'delete'))","tryCatchPattern":null,"preventionTips":["Lock redis-py to a modern version in your lockfile","Smoke-test cache writes at startup, not at first production request"],"tags":["redis","cache-write","dependency","version"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}