{"id":"f1061cfd34b35145","repo":"go-redis/redis","slug":"redis-submit-requires-the-deferred-autopipeliner","errorCode":null,"errorMessage":"redis: Submit requires the deferred autopipeliner (AsyncAutoPipeline); on the blocking face use the typed methods or Do","messagePattern":"redis: Submit requires the deferred autopipeliner \\(AsyncAutoPipeline\\); on the blocking face use the typed methods or Do","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"autopipeline.go","lineNumber":1343,"sourceCode":"\t\t}\n\t\t// runOutsidePipeline sets the command ready itself on the deferred\n\t\t// face; the returned batch completes when the command has executed.\n\t\treturn AutoFuture{cmd: cmd, batch: ap.runOutsidePipeline(ctx, cmd)}\n\t}\n\t// No finish here: enqueue stamps ready under the stripe lock, before the\n\t// command is visible to any drain (the error paths above still go through\n\t// finish for uniform accessor behavior).\n\treturn AutoFuture{cmd: cmd, batch: ap.enqueue(cmd)}\n}\n\n// ErrSubmitBlockingFace rejects Submit on the blocking face: Submit does not\n// wait, so a windowed caller could have several commands in flight at once —\n// but the blocking face stripes its enqueue queue on the strength of every\n// caller waiting per command, and a non-waiting window there can be reordered.\n// The deferred face (AsyncAutoPipeline) is built for exactly that usage.\n//\n// EXPERIMENTAL: this API is subject to change, use with caution.\nvar ErrSubmitBlockingFace = errors.New(\n\t\"redis: Submit requires the deferred autopipeliner (AsyncAutoPipeline); on the blocking face use the typed methods or Do\")\n\n// errZeroAutoFuture is returned by Wait/WaitContext on a zero AutoFuture.\nvar errZeroAutoFuture = errors.New(\"redis: Wait on a zero AutoFuture\")\n\n// errDoNoArgs is returned by Do when called without a command.\nvar errDoNoArgs = errors.New(\"redis: AutoPipeliner.Do requires at least one argument\")\n\n// ErrAutoPipelineTimeout is set on drained commands when a flush could not\n// obtain a batch permit within the engine's internal backstop — the engine is\n// overloaded or an in-flight batch is wedged (e.g. read timeouts disabled on\n// a dead peer). It is deliberately NOT context.DeadlineExceeded: the caller's\n// own context did not expire, and errors.Is(err, context.DeadlineExceeded)\n// must not fire for an internal engine timeout.\n//\n// EXPERIMENTAL: this API is subject to change, use with caution.\nvar ErrAutoPipelineTimeout = errors.New(\n\t\"redis: autopipeline: no batch permit within the internal backstop (engine overloaded or a batch is wedged)\")","sourceCodeStart":1325,"sourceCodeEnd":1361,"githubUrl":"https://github.com/go-redis/redis/blob/36d97525cd8076aed67cddf54778e9ea84550929/autopipeline.go#L1325-L1361","documentation":"Error \"redis: Submit requires the deferred autopipeliner (AsyncAutoPipeline); on the blocking face use the typed methods or Do\" thrown in go-redis/redis.","triggerScenarios":"Thrown at autopipeline.go:1343 when the library encounters an invalid state.","commonSituations":"Guard call sites by keeping the AsyncAutoPipeline handle in its own type so Submit cannot be invoked on the blocking face.","solutions":["Create the autopipeliner with client.AsyncAutoPipeline() (the deferred/async face) before calling Submit","On the blocking face returned by client.AutoPipeline(), use typed methods (Get, Set, ...) or Do instead of Submit"],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"analyzedSha":"36d97525cd8076aed67cddf54778e9ea84550929","analyzedAt":"2026-08-06T01:08:27.376Z","schemaVersion":2}