BerriAI/litellm · error · Exception

Redis client cannot set cache. Attribute not found.

Error message

Redis client cannot set cache. Attribute not found.

What it means

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.

Source

Thrown at litellm/caching/redis_cache.py:713

                    call_type=f"async_set_cache <- {_get_call_stack_info()}",
                )
            )
            verbose_logger.error(
                "LiteLLM Redis Caching: async set() - Got exception from REDIS %s, key=%r, value=%r",
                str(e),
                key,
                value,
            )
            raise e

        key = self.check_and_fix_namespace(key=key)
        ttl: Final = self.get_ttl(**kwargs)
        nx: Final = kwargs.get("nx", False)
        print_verbose(f"Set ASYNC Redis Cache: key: {key}\nValue {value}\nttl={ttl}")

        try:
            if not hasattr(_redis_client, "set"):
                raise Exception("Redis client cannot set cache. Attribute not found.")
            result: Final = await _redis_client.set(
                name=key,
                value=json.dumps(value),
                nx=nx,
                ex=ttl,
            )
            print_verbose(f"Successfully Set ASYNC Redis Cache: key: {key}\nValue {value}\nttl={ttl}")
            end_time = time.time()
            _duration = end_time - start_time
            asyncio.create_task(
                self.service_logger_obj.async_service_success_hook(
                    service=ServiceTypes.REDIS,
                    duration=_duration,
                    call_type=f"async_set_cache <- {_get_call_stack_info()}",
                    start_time=start_time,
                    end_time=end_time,
                    parent_otel_span=_get_parent_otel_span_from_kwargs(kwargs),
                    event_metadata={"key": key},

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Upgrade redis-py to a current version: pip install -U 'redis>=5'
  2. If you pass a custom async client to RedisCache, make sure it delegates .set (and the other standard commands)
  3. In tests, replace the stub with fakeredis.aioredis.FakeRedis
Defensive patterns

Strategy: validation

Validate before calling

def assert_cache_ready(cache) -> None:
    client = getattr(cache, 'async_client', None) or cache.init_async_client()
    for op in ('set', 'get', 'delete'):
        if not hasattr(client, op):
            raise RuntimeError(f'Async redis client missing .{op}; upgrade redis-py (>=5) or fix injected client')

Type guard

def is_functional_async_redis(client: Any) -> TypeGuard[Any]:
    return all(hasattr(client, m) for m in ('set', 'get', 'delete'))

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/decbf14e120858b3. Report an issue: GitHub.