{"record":{"id":"5b706a8436470f00","repo":"redis/redis-py","slug":"async-redis-client-does-not-support-class-deletion","errorCode":null,"errorMessage":"Async Redis client does not support class deletion","messagePattern":"Async Redis client does not support class deletion","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"redis/commands/core.py","lineNumber":4809,"sourceCode":"        the given ``minmatchlen``.\n        If ``withmatchlen`` the length of the match also will be returned.\n        For more information, see https://redis.io/commands/lcs\n        \"\"\"\n        pieces: list[str | int] = [key1, key2]\n        if len:\n            pieces.append(\"LEN\")\n        if idx:\n            pieces.append(\"IDX\")\n        if minmatchlen is not None and minmatchlen != 0:\n            pieces.extend([\"MINMATCHLEN\", minmatchlen])\n        if withmatchlen:\n            pieces.append(\"WITHMATCHLEN\")\n        return self.execute_command(\"LCS\", *pieces, keys=[key1, key2])\n\n\nclass AsyncBasicKeyCommands(BasicKeyCommands):\n    def __delitem__(self, name: KeyT):\n        raise TypeError(\"Async Redis client does not support class deletion\")\n\n    def __contains__(self, name: KeyT):\n        raise TypeError(\"Async Redis client does not support class inclusion\")\n\n    def __getitem__(self, name: KeyT):\n        raise TypeError(\"Async Redis client does not support class retrieval\")\n\n    def __setitem__(self, name: KeyT, value: EncodableT):\n        raise TypeError(\"Async Redis client does not support class assignment\")\n\n    async def watch(self, *names: KeyT) -> None:\n        return super().watch(*names)\n\n    async def unwatch(self) -> None:\n        return super().unwatch()\n\n\nclass ListCommands(CommandsProtocol):","sourceCodeStart":4791,"sourceCodeEnd":4827,"githubUrl":"https://github.com/redis/redis-py/blob/6a6b581b48225afa0b76912d1028c6035baee932/redis/commands/core.py#L4791-L4827","documentation":"Raised by AsyncBasicKeyCommands.__delitem__ (a TypeError) when you use 'del async_client[key]' on an async Redis client. The sync client maps del client[key] to DELETE, but the async client cannot because Python dunder methods cannot be async (awaitable), so the override raises immediately to prevent silent misuse.","triggerScenarios":"Writing 'del redis_async[key]' or 'del redis_async['mykey']' where redis_async is a redis.asyncio.Redis instance. Code ported verbatim from the sync client that used item deletion.","commonSituations":"Migrating from redis.Redis to redis.asyncio.Redis and leaving dict-style deletion syntax in place. Code that generically calls __delitem__ on any mapping-like object.","solutions":["Replace 'del client[key]' with 'await client.delete(key)'.","If deleting multiple keys, use 'await client.delete(*keys)'."],"exampleFix":"# before\ndel client['mykey']\n\n# after\nawait client.delete('mykey')","handlingStrategy":"validation","validationCode":"# Never use del on an async client; call delete explicitly.\nawait client.delete(key)  # instead of del client[key]","typeGuard":"import redis\n\ndef is_async_client(c) -> bool:\n    return isinstance(c, (redis.asyncio.Redis, redis.asyncio.RedisCluster))\n\n# usage: if is_async_client(client): await client.delete(key) else: del client[key]","tryCatchPattern":"try:\n    del client[key]\nexcept TypeError as e:\n    if 'class deletion' in str(e):\n        await client.delete(key)\n    else:\n        raise","preventionTips":["When migrating to redis.asyncio, grep for 'del client[' and replace with await client.delete().","Treat the async client as await-only; never use dict/item protocol on it.","Run a quick grep for dunder usage (__delitem__/__setitem__/__getitem__/__contains__) on async clients."],"tags":["async","dunder","delete","typeerror","sync-to-async"],"backgroundTag":null,"analyzedSha":"6a6b581b48225afa0b76912d1028c6035baee932","analyzedAt":"2026-08-10T12:52:44.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}