{"record":{"id":"48b6b908db06e6f1","repo":"redis/go-redis","slug":"redis-cannot-pipeline-command-q-with-request-pol","errorCode":null,"errorMessage":"redis: cannot pipeline command %q with request policy ReqAllNodes/ReqAllShards/ReqMultiShard; Note: This behavior is subject to change in the future","messagePattern":"redis: cannot pipeline command %q with request policy ReqAllNodes/ReqAllShards/ReqMultiShard; Note: This behavior is subject to change in the future","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"osscluster.go","lineNumber":1899,"sourceCode":"// instead of splitting every batch across all nodes at flush. Cluster slots are\n// contiguous per node, so bucketing by slot range (slot*shards/16384) keeps a\n// node's slots together. Keyless commands hash to slot -1 → bucket 0; multi-node\n// commands are already rejected from pipelines, so only single-node commands\n// reach here.\nfunc (c *ClusterClient) installAutoPipelineSharding(ap *AutoPipeliner) {\n\t// Reject commands whose request policy cannot ride a pipeline (ReqAllNodes/\n\t// ReqAllShards/ReqMultiShard) at submit, BEFORE they can join a merged\n\t// batch: mapCmdsByNode fails a whole mapping on such a command (user\n\t// pipelines are all-or-nothing), and one autopipeline caller must not be\n\t// able to poison unrelated callers' batches. Rejecting here also keeps the\n\t// lone-command fast path consistent with batched dispatch — the command is\n\t// refused regardless of what it happens to coalesce with.\n\tap.setPreflight(func(ctx context.Context, cmd Cmder) error {\n\t\tif c.cmdInfoResolver == nil {\n\t\t\treturn nil\n\t\t}\n\t\tif policy := c.cmdInfoResolver.GetCommandPolicy(ctx, cmd); policy != nil && !policy.CanBeUsedInPipeline() {\n\t\t\treturn fmt.Errorf(\n\t\t\t\t\"redis: cannot pipeline command %q with request policy ReqAllNodes/ReqAllShards/ReqMultiShard; Note: This behavior is subject to change in the future\", cmd.Name(),\n\t\t\t)\n\t\t}\n\t\treturn nil\n\t})\n\t// Commands whose routing is not slot-derived must not be coalesced: a solo\n\t// flush reaches ClusterClient.process and its special handling (FT.CURSOR\n\t// READ/DEL are sticky to the node holding the cursor), but inside a batch\n\t// mapCmdsByNode routes by slot and can hit the wrong shard — visible only\n\t// under concurrent traffic, which is the worst way to find it. Divert them\n\t// instead of rejecting: they work fine on their own connection (review\n\t// finding by codex on #3942).\n\tap.setMustDivert(func(ctx context.Context, cmd Cmder) bool {\n\t\tif c.cmdInfoResolver == nil {\n\t\t\treturn false\n\t\t}\n\t\tpolicy := c.cmdInfoResolver.GetCommandPolicy(ctx, cmd)\n\t\treturn policy != nil && policy.Request == routing.ReqSpecial","sourceCodeStart":1881,"sourceCodeEnd":1917,"githubUrl":"https://github.com/redis/go-redis/blob/c5cad058c72f58370553b48566302303cf8a2e89/osscluster.go#L1881-L1917","documentation":"Error \"redis: cannot pipeline command %q with request policy ReqAllNodes/ReqAllShards/ReqMultiShard; Note: This behavior is subject to change in the future\" thrown in redis/go-redis.","triggerScenarios":"Thrown at osscluster.go:1899 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":[],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"c5cad058c72f58370553b48566302303cf8a2e89","analyzedAt":"2026-09-01T06:50:53.388Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}