{"record":{"id":"57e42b9255047bc2","repo":"redis/redis-py","slug":"async-redis-client-does-not-support-class-retrieva","errorCode":null,"errorMessage":"Async Redis client does not support class retrieval","messagePattern":"Async Redis client does not support class retrieval","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"redis/commands/core.py","lineNumber":4815,"sourceCode":"            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):\n    \"\"\"\n    Redis commands for List data type.\n    see: https://redis.io/topics/data-types#lists\n    \"\"\"\n\n    @overload","sourceCodeStart":4797,"sourceCodeEnd":4833,"githubUrl":"https://github.com/redis/redis-py/blob/6a6b581b48225afa0b76912d1028c6035baee932/redis/commands/core.py#L4797-L4833","documentation":"Raised by AsyncBasicKeyCommands.__getitem__ (a TypeError) when you use 'async_client[key]' to read a value. The sync client maps client[key] to GET (raising KeyError on missing), but the async dunder cannot be awaited, so it is disabled to prevent receiving a coroutine instead of the value.","triggerScenarios":"Writing \"value = client['mykey']\" where client is a redis.asyncio.Redis instance.","commonSituations":"Direct port of sync code that used dict-style key access. Generic code that treats the client as a mapping.","solutions":["Replace \"client[key]\" with \"await client.get(key)\".","If you relied on KeyError for missing keys, check for None or use a helper that raises KeyError when get returns None."],"exampleFix":"# before\nvalue = client['mykey']\n\n# after\nvalue = await client.get('mykey')","handlingStrategy":"validation","validationCode":"# Never use client[key] on an async client; call get explicitly.\nvalue = await client.get(key)  # instead of client[key]","typeGuard":"import redis\n\ndef is_async_client(c) -> bool:\n    return isinstance(c, (redis.asyncio.Redis, redis.asyncio.RedisCluster))","tryCatchPattern":"try:\n    value = client[key]\nexcept TypeError as e:\n    if 'class retrieval' in str(e):\n        value = await client.get(key)\n    else:\n        raise","preventionTips":["Replace client[key] with await client.get(key) in all async code paths.","If you relied on KeyError for missing keys, check value is None and raise KeyError yourself."],"tags":["async","dunder","getitem","get","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"}