BerriAI/litellm · error · ValueError
Redis client does not support Lua script registration
Error message
Redis client does not support Lua script registration
What it means
When LiteLLM registers a Lua script on the async Redis client it tries, in order, client.register_script (standard redis-py) and client.script_load (cluster fallback). If the client object exposes neither method, registration is impossible and raises ValueError. This almost always means the installed redis-py version is too old, a non-redis-py client was injected, or a mock/stub client is being used.
Source
Thrown at litellm/caching/redis_cache.py:668
if hasattr(_redis_client, "register_script"):
registered_script: Final = _redis_client.register_script(script)
async def standalone_executor(keys: Sequence[str], args: Sequence[Any], client: Any = None) -> Any:
namespaced_keys: Final = tuple(self.check_and_fix_namespace(key=key) for key in keys)
return await registered_script(keys=namespaced_keys, args=args, client=client)
return standalone_executor
if hasattr(_redis_client, "script_load"):
script_sha: Final = _redis_client.script_load(script)
async def cluster_executor(keys: Sequence[str], args: Sequence[Any], client: Any = None) -> Any:
namespaced_keys: Final = tuple(self.check_and_fix_namespace(key=key) for key in keys)
return await _redis_client.evalsha(script_sha, len(namespaced_keys), *namespaced_keys, *args)
return cluster_executor
raise ValueError("Redis client does not support Lua script registration")
@_redis_circuit_breaker_guard
async def async_set_cache(self, key, value, **kwargs):
from redis.asyncio import Redis
if key is None:
verbose_logger.debug(
"LiteLLM Redis Caching: async set() skipped — key is None, value=%r",
value,
)
return None
start_time: Final = time.time()
try:
_redis_client: Final[Redis] = self.init_async_client()
except Exception as e:
end_time = time.time()
_duration = end_time - start_timeView on GitHub (pinned to 6c2dcb801b)
Solutions
- Upgrade redis-py: pip install -U 'redis>=5' (redis.asyncio ships in the same package)
- If injecting a custom async client, ensure it exposes register_script (or at minimum script_load)
- In tests, use fakeredis.aioredis.FakeRedis which implements register_script
Example fix
# before pip install 'redis==3.5.3' # no async register_script # after pip install -U 'redis>=5.0'
Defensive patterns
Strategy: validation
Validate before calling
from redis.asyncio import Redis as AsyncRedis
def supports_lua(client) -> bool:
return hasattr(client, 'register_script') or hasattr(client, 'script_load')
# before wiring RedisCache with a custom client:
assert supports_lua(my_async_client), 'custom redis client must support Lua script registration' Type guard
def is_lua_capable_redis_client(client: Any) -> TypeGuard[AsyncRedis]:
return hasattr(client, 'register_script') or hasattr(client, 'script_load') Prevention
- Pin redis>=5 in requirements
- Run a startup smoke test that writes and reads through the cache
- Use fakeredis.aioredis.FakeRedis in tests — it implements register_script
When it happens
Trigger: Using a very old redis-py(<4.x)/redis.asyncio version lacking both APIs; passing a custom client wrapper or mock object into RedisCache that does not expose register_script or script_load; features that run Lua scripts (e.g. distributed locking or atomic cache ops) then trigger _register_script_for_current_loop.
Common situations: Pinning redis<4 in requirements; test suites substituting fakeredis/mocks without script support; exotic managed environments shipping stripped redis clients.
Related errors
- Redis client cannot set cache. Attribute not found.
- Missing google.cloud package. Run `pip install --upgrade goo
- Error while creating new collection
- Redis circuit breaker is open — skipping {name}
- similarity_threshold must be provided, passed None
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/02ba940a1c22c3cc.
Report an issue: GitHub.