{"id":"6c83ef3086c5acab","repo":"go-redis/redis","slug":"redis-autopipeline-is-not-supported-by-ring","errorCode":null,"errorMessage":"redis: AutoPipeline is not supported by Ring","messagePattern":"redis: AutoPipeline is not supported by Ring","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ring.go","lineNumber":872,"sourceCode":"func (c *Ring) Pipelined(ctx context.Context, fn func(Pipeliner) error) ([]Cmder, error) {\n\treturn c.Pipeline().Pipelined(ctx, fn)\n}\n\nfunc (c *Ring) Pipeline() Pipeliner {\n\tpipe := Pipeline{\n\t\texec: pipelineExecer(c.processPipelineHook),\n\t}\n\tpipe.init()\n\treturn &pipe\n}\n\n// ErrRingAutoPipelineUnsupported is returned by Ring's AutoPipeline /\n// AsyncAutoPipeline (and their WithOptions forms); check for it with\n// errors.Is. Autopipelining is not implemented for Ring; use the per-shard\n// clients or a ClusterClient. Ring is part of the UniversalClient\n// interface, so these methods exist to satisfy it and fail explicitly rather\n// than being silently absent.\nvar ErrRingAutoPipelineUnsupported = errors.New(\"redis: AutoPipeline is not supported by Ring\")\n\n// AutoPipeline is not supported by Ring; it returns ErrRingAutoPipelineUnsupported.\nfunc (c *Ring) AutoPipeline() (*AutoPipeliner, error) {\n\treturn c.AutoPipelineWithOptions(nil)\n}\n\n// AutoPipelineWithOptions is not supported by Ring; it returns ErrRingAutoPipelineUnsupported.\nfunc (c *Ring) AutoPipelineWithOptions(config *AutoPipelineOptions) (*AutoPipeliner, error) {\n\treturn nil, ErrRingAutoPipelineUnsupported\n}\n\n// AsyncAutoPipeline is not supported by Ring; it returns ErrRingAutoPipelineUnsupported.\nfunc (c *Ring) AsyncAutoPipeline() (*AutoPipeliner, error) {\n\treturn c.AsyncAutoPipelineWithOptions(nil)\n}\n\n// AsyncAutoPipelineWithOptions is not supported by Ring; it returns ErrRingAutoPipelineUnsupported.\nfunc (c *Ring) AsyncAutoPipelineWithOptions(config *AutoPipelineOptions) (*AutoPipeliner, error) {","sourceCodeStart":854,"sourceCodeEnd":890,"githubUrl":"https://github.com/go-redis/redis/blob/36d97525cd8076aed67cddf54778e9ea84550929/ring.go#L854-L890","documentation":"ErrRingAutoPipelineUnsupported is returned by Ring.AutoPipeline, AutoPipelineWithOptions, AsyncAutoPipeline, and AsyncAutoPipelineWithOptions. Autopipelining is implemented for Client and ClusterClient but not for Ring; the methods exist only to satisfy the UniversalClient interface and fail explicitly so callers don't get silent no-ops. Check with errors.Is(err, redis.ErrRingAutoPipelineUnsupported).","triggerScenarios":"Calling AutoPipeline() or AsyncAutoPipeline() on a *redis.Ring instance. UniversalClient code that branches on interface type and lands on a Ring. Migrating autopipeline code from a Client to a Ring-backed setup.","commonSituations":"Using UniversalClient and assuming all client types support autopipelining. Switching from a single-node Client to a Ring for client-side sharding without realizing autopipelining isn't supported there. Copying autopipeline code from a Client example into Ring code.","solutions":["Use a ClusterClient instead of a Ring if you need autopipelining with multiple nodes (cluster protocol is supported).","Use Ring's regular Pipeline() / Pipelined() for manual batching instead of autopipelining.","Access the underlying per-shard Clients directly and enable autopipelining on each one."],"exampleFix":"// before — Ring does not support autopipelining\nring := redis.NewRing(&redis.RingOptions{Addrs: ...})\nap, err := ring.AutoPipeline() // err = ErrRingAutoPipelineUnsupported\n\n// after — use manual pipelining on the Ring\npipe := ring.Pipeline()\npipe.Set(ctx, \"k\", \"v\", 0)\ncmds, err := pipe.Exec(ctx)\n\n// or switch to ClusterClient if you want autopipelining\ncluster := redis.NewClusterClient(&redis.ClusterOptions{Addrs: ...})\nap, err := cluster.AutoPipeline()","handlingStrategy":"validation","validationCode":"func supportsAutoPipeline(c redis.UniversalClient) bool {\n    switch c.(type) {\n    case *redis.Client, *redis.ClusterClient:\n        return true\n    }\n    return false // *redis.Ring returns ErrRingAutoPipelineUnsupported\n}","typeGuard":"var _ redis.UniversalClient = (*redis.Ring)(nil)\n\nfunc isRing(c redis.UniversalClient) bool {\n    _, ok := c.(*redis.Ring)\n    return ok\n}","tryCatchPattern":"ap, err := c.AutoPipeline()\nif err != nil {\n    if errors.Is(err, redis.ErrRingAutoPipelineUnsupported) {\n        // fall back to manual Pipeline() or switch to ClusterClient\n    }\n}","preventionTips":["Type-assert UniversalClient to *redis.Ring before calling AutoPipeline.","Prefer ClusterClient over Ring when you need autopipelining across nodes.","Document which client types support autopipelining in your wrapper layer."],"tags":["ring","autopipeline","unsupported","universal-client","api-misuse"],"analyzedSha":"36d97525cd8076aed67cddf54778e9ea84550929","analyzedAt":"2026-08-06T01:08:27.376Z","schemaVersion":2}