{"id":"b22ab57ae64e6738","repo":"redis/redis-py","slug":"invalid-option-for-cluster-failover-command-opti","errorCode":null,"errorMessage":"Invalid option for CLUSTER FAILOVER command: {option}","messagePattern":"Invalid option for CLUSTER FAILOVER command: (.+?)","errorType":"exception","errorClass":"RedisError","httpStatus":null,"severity":"error","filePath":"redis/commands/cluster.py","lineNumber":644,"sourceCode":"        target_node: \"TargetNodesT\",\n        option: str | None = None,\n    ) -> Awaitable[bool]: ...\n\n    def cluster_failover(\n        self, target_node: \"TargetNodesT\", option: str | None = None\n    ) -> bool | Awaitable[bool]:\n        \"\"\"\n        Forces a slave to perform a manual failover of its master\n        Sends to specified 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-failover\n        \"\"\"\n        if option:\n            if option.upper() not in [\"FORCE\", \"TAKEOVER\"]:\n                raise RedisError(\n                    f\"Invalid option for CLUSTER FAILOVER command: {option}\"\n                )\n            else:\n                return self.execute_command(\n                    \"CLUSTER FAILOVER\", option, target_nodes=target_node\n                )\n        else:\n            return self.execute_command(\"CLUSTER FAILOVER\", target_nodes=target_node)\n\n    @overload\n    def cluster_info(\n        self: SyncClientProtocol, target_nodes: \"TargetNodesT\" | None = None\n    ) -> dict[str, str]: ...\n\n    @overload\n    def cluster_info(\n        self: AsyncClientProtocol, target_nodes: \"TargetNodesT\" | None = None\n    ) -> Awaitable[dict[str, str]]: ...","sourceCodeStart":626,"sourceCodeEnd":662,"githubUrl":"https://github.com/redis/redis-py/blob/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/commands/cluster.py#L626-L662","documentation":"Raised in RedisClusterCommands.cluster_failover (redis/commands/cluster.py:644) when an option is supplied whose uppercase form is neither 'FORCE' nor 'TAKEOVER'. CLUSTER FAILOVER only accepts those two optional modifiers (plus no option at all); any other string is rejected before the command is sent.","triggerScenarios":"Calling rc.cluster_failover(target_node=replica, option='ABORT'), option='force-takeover', option='SYNC', or any value not equal (case-insensitive) to FORCE or TAKEOVER. Typos like 'FORCE ' (trailing space) or 'TAKE_OVER' also trip it.","commonSituations":"Guessing option names from memory. Passing user input or config values without validation. Copying examples from sources that invented option names. Localized/uppercased values with unexpected whitespace.","solutions":["Pass one of the allowed values: option=None (plain failover), option='FORCE', or option='TAKEOVER' (case-insensitive).","Validate/normalize user-supplied options before calling: opt = option.upper() if option else None; assert opt in (None,'FORCE','TAKEOVER').","Strip whitespace and reject unknown values upstream so invalid input never reaches the client."],"exampleFix":"# before\nrc.cluster_failover(target_node=replica, option='TAKE_OVER')  # raises\n\n# after\nrc.cluster_failover(target_node=replica, option='TAKEOVER')","handlingStrategy":"validation","validationCode":"ALLOWED_FAILOVER_OPTIONS = {None, 'FORCE', 'TAKEOVER'}\n\ndef normalize_failover_option(option):\n    if option is None:\n        return None\n    opt = option.strip().upper()\n    if opt not in ALLOWED_FAILOVER_OPTIONS:\n        raise ValueError(f'CLUSTER FAILOVER option must be FORCE or TAKEOVER, got {option!r}')\n    return opt\n\ndef safe_failover(client, target_node, option=None):\n    return client.cluster_failover(\n        target_node=target_node, option=normalize_failover_option(option)\n    )","typeGuard":null,"tryCatchPattern":"from redis.exceptions import RedisError\n\ntry:\n    rc.cluster_failover(target_node=replica, option=user_opt)\nexcept RedisError as e:\n    if 'Invalid option for CLUSTER FAILOVER' in str(e):\n        opt = user_opt.strip().upper() if user_opt else None\n        if opt in ('FORCE', 'TAKEOVER'):\n            rc.cluster_failover(target_node=replica, option=opt)\n        else:\n            raise\n    else:\n        raise","preventionTips":["Pass only None, 'FORCE', or 'TAKEOVER' (case-insensitive) to cluster_failover(option=...).","Normalize and validate user-supplied option strings before they reach the client.","Strip whitespace from config-driven values to avoid silent mismatches."],"tags":["cluster","validation","failover","api-misuse"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}