{"record":{"id":"e7f0904d20e6e089","repo":"redis/redis-py","slug":"error-calling-pipelined-function-name-is-blocke","errorCode":null,"errorMessage":"ERROR: Calling pipelined function {name} is blocked when running redis in cluster mode...","messagePattern":"ERROR: Calling pipelined function (.+?) is blocked when running redis in cluster mode\\.\\.\\.","errorType":"exception","errorClass":"RedisClusterException","httpStatus":null,"severity":"error","filePath":"redis/cluster.py","lineNumber":3759,"sourceCode":"\n    def script_load_for_pipeline(self, *args, **kwargs):\n        self._execution_strategy.script_load_for_pipeline(*args, **kwargs)\n\n    def delete(self, *names):\n        self._execution_strategy.delete(*names)\n\n    def unlink(self, *names):\n        self._execution_strategy.unlink(*names)\n\n\ndef block_pipeline_command(name: str) -> Callable[..., Any]:\n    \"\"\"\n    Prints error because some pipelined commands should\n    be blocked when running in cluster-mode\n    \"\"\"\n\n    def inner(*args, **kwargs):\n        raise RedisClusterException(\n            f\"ERROR: Calling pipelined function {name} is blocked \"\n            f\"when running redis in cluster mode...\"\n        )\n\n    return inner\n\n\ndef is_zero_key_eval_command(*args) -> bool:\n    \"\"\"\n    True for EVAL/EVALSHA with numkeys=0 (any primary).\n    \"\"\"\n    if len(args) < 3:\n        return False\n    if str(args[0]).upper() not in (\"EVAL\", \"EVALSHA\"):\n        return False\n    try:\n        return int(args[2]) == 0\n    except (TypeError, ValueError):","sourceCodeStart":3741,"sourceCodeEnd":3777,"githubUrl":"https://github.com/redis/redis-py/blob/6a6b581b48225afa0b76912d1028c6035baee932/redis/cluster.py#L3741-L3777","documentation":"Raised as a RedisClusterException by the block_pipeline_command wrapper (cluster.py:3752-3764) when a command listed in PIPELINE_BLOCKED_COMMANDS is called on a ClusterPipeline instance. These commands (BGREWRITEAOF, CONFIG, FLUSHALL, KEYS, MGET, SCAN, SCRIPT, SHUTDOWN, SORT, etc. — ~60 commands) cannot be safely pipelined in cluster mode because they are multi-node, stateful, or semantically incompatible with the pipeline abstraction. The wrapper is installed via setattr at cluster.py:3853-3856.","triggerScenarios":"Calling pipe.keys('*'), pipe.config_set(...), pipe.flushdb(), pipe.scan(), pipe.mget(...), or any of the ~60 blocked commands on a pipeline obtained from client.pipeline() in cluster mode.","commonSituations":"Porting pipelined batch code from standalone Redis to cluster mode, or attempting to pipeline admin/diagnostic commands.","solutions":["Call the blocked command directly on the client (not through the pipeline): client.keys('*') instead of pipe.keys('*').","For multi-key commands like MGET/SCAN, execute them per-node by targeting specific nodes with target_nodes, or iterate over get_primaries().","For truly batched key operations, use individual pipe.get(key) / pipe.set(key, val) calls (which are supported) and then pipe.execute()."],"exampleFix":"// before\npipe = client.pipeline()\npipe.keys('*')\npipe.execute()\n\n// after\nall_keys = []\nfor node in client.get_primaries():\n    all_keys.extend(client.keys('*', target_nodes=[node]))","handlingStrategy":"validation","validationCode":"from redis.cluster import PIPELINE_BLOCKED_COMMANDS\nblocked_lower = {c.replace(' ', '_').lower() for c in PIPELINE_BLOCKED_COMMANDS}\n\ndef safe_pipeline_call(pipe, method_name, *args, **kwargs):\n    if method_name.lower() in blocked_lower:\n        raise ValueError(f'{method_name} is blocked in cluster pipeline; call on client directly')\n    return getattr(pipe, method_name)(*args, **kwargs)","typeGuard":"def is_pipeline_blocked(method_name: str) -> bool:\n    from redis.cluster import PIPELINE_BLOCKED_COMMANDS\n    blocked = {c.replace(' ', '_').lower() for c in PIPELINE_BLOCKED_COMMANDS}\n    return method_name.lower() in blocked","tryCatchPattern":"from redis.exceptions import RedisClusterException\ntry:\n    pipe.keys('*')\nexcept RedisClusterException as e:\n    if 'is blocked' in str(e):\n        result = client.keys('*')  # call on client, not pipeline","preventionTips":["Check PIPELINE_BLOCKED_COMMANDS before calling a command on a cluster pipeline.","Call blocked commands directly on the client, not through the pipeline.","For multi-node commands like KEYS/SCAN, iterate over get_primaries() with target_nodes."],"tags":["pipeline","blocked-command","cluster","multi-node"],"backgroundTag":null,"analyzedSha":"6a6b581b48225afa0b76912d1028c6035baee932","analyzedAt":"2026-08-10T12:52:44.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}