{"id":"bc47f76a390fedd6","repo":"redis/redis-py","slug":"invalid-slot-state-state","errorCode":null,"errorMessage":"Invalid slot state: {state}","messagePattern":"Invalid slot state: (.+?)","errorType":"exception","errorClass":"RedisError","httpStatus":null,"severity":"error","filePath":"redis/commands/cluster.py","lineNumber":890,"sourceCode":"    def cluster_setslot(\n        self, target_node: \"TargetNodesT\", node_id: str, slot_id: int, state: str\n    ) -> bool | Awaitable[bool]:\n        \"\"\"\n        Bind an hash slot to a specific node\n\n        :target_node: 'ClusterNode'\n            The node to execute the command on\n\n        For more information see https://redis.io/commands/cluster-setslot\n        \"\"\"\n        if state.upper() in (\"IMPORTING\", \"NODE\", \"MIGRATING\"):\n            return self.execute_command(\n                \"CLUSTER SETSLOT\", slot_id, state, node_id, target_nodes=target_node\n            )\n        elif state.upper() == \"STABLE\":\n            raise RedisError('For \"stable\" state please use cluster_setslot_stable')\n        else:\n            raise RedisError(f\"Invalid slot state: {state}\")\n\n    @overload\n    def cluster_setslot_stable(self: SyncClientProtocol, slot_id: int) -> bool: ...\n\n    @overload\n    def cluster_setslot_stable(\n        self: AsyncClientProtocol, slot_id: int\n    ) -> Awaitable[bool]: ...\n\n    def cluster_setslot_stable(self, slot_id: int) -> bool | Awaitable[bool]:\n        \"\"\"\n        Clears migrating / importing state from the slot.\n        It determines by it self what node the slot is in and sends it there.\n\n        For more information see https://redis.io/commands/cluster-setslot\n        \"\"\"\n        return self.execute_command(\"CLUSTER SETSLOT\", slot_id, \"STABLE\")\n","sourceCodeStart":872,"sourceCodeEnd":908,"githubUrl":"https://github.com/redis/redis-py/blob/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/commands/cluster.py#L872-L908","documentation":"Raised by cluster_setslot() when the state argument is not one of IMPORTING, NODE, MIGRATING, or STABLE. It is a client-side argument-validation guard (RedisError) fired before any command is sent to the server, so the slot is never touched. The invalid value is interpolated into the message to help spot typos or unexpected enums.","triggerScenarios":"Calling cluster_setslot(target_node, node_id, slot_id, state) where state is anything other than the four known strings (case-insensitive) — e.g. 'STABLEE', 'migrate', 'IMPORT', an empty string, None.upper()'d path, or a value sourced from a misconfigured variable.","commonSituations":"Typos in the state string; passing a server-side synonym that the client does not recognize; data-driven code feeding an unvalidated state from config or a DB; using lowercase 'stable' intentionally but hitting the dedicated-method error is a different (240) path.","solutions":["Pass one of 'IMPORTING', 'NODE', 'MIGRATING' (or 'STABLE', but then prefer cluster_setslot_stable).","Validate/normalize the state against an allow-list before calling cluster_setslot.","Check the source of the state value for truncation or wrong casing."],"exampleFix":"# before\nr.cluster_setslot(node, node_id, slot_id, state=raw_state)\n# after\n_ALLOWED = {'IMPORTING', 'NODE', 'MIGRATING'}\nstate = raw_state.upper()\nif state == 'STABLE':\n    r.cluster_setslot_stable(slot_id)\nelif state in _ALLOWED:\n    r.cluster_setslot(node, node_id, slot_id, state=state)\nelse:\n    raise ValueError(f'unsupported slot state: {raw_state}')","handlingStrategy":"validation","validationCode":"_SLOT_STATES = {'IMPORTING', 'NODE', 'MIGRATING', 'STABLE'}\nstate = str(state).upper()\nif state not in _SLOT_STATES:\n    raise ValueError(f'Unsupported slot state: {state!r}')","typeGuard":"def is_valid_slot_state(state: str) -> bool:\n    return str(state).upper() in {'IMPORTING', 'NODE', 'MIGRATING', 'STABLE'}","tryCatchPattern":"from redis.exceptions import RedisError\ntry:\n    client.cluster_setslot(target_node, node_id, slot_id, state=state)\nexcept RedisError as e:\n    if 'Invalid slot state' in str(e):\n        log.error('Bad slot state %r; allowed: IMPORTING/NODE/MIGRATING/STABLE', state)\n    raise","preventionTips":["Keep an allow-list constant of slot states near your reshard code.","Never source state from unvalidated user/config input."],"tags":["cluster","setslot","validation","argument-error"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}