{"id":"eda97e6046f46668","repo":"go-redis/redis","slug":"redis-autopipelineoptions-maxbatchsize-d-must-be","errorCode":null,"errorMessage":"redis: AutoPipelineOptions.MaxBatchSize=%d must be >= 0","messagePattern":"redis: AutoPipelineOptions\\.MaxBatchSize=(.+?) must be >= 0","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"autopipeline.go","lineNumber":225,"sourceCode":"// error if MaxConcurrentBatches > 1 without Unordered: true — raising\n// concurrency gives up command ordering, so the caller must opt in explicitly.\n//\n// Validate()==nil does not guarantee construction succeeds: rules that need\n// the face (e.g. NumShards>1 requires Unordered on the deferred face) are\n// enforced by the AutoPipeline/AsyncAutoPipeline getters. Note also that\n// Options.AutoPipelineOptions is validated lazily — on the first getter\n// call, not in NewClient.\nfunc (cfg *AutoPipelineOptions) Validate() error {\n\tif cfg.MaxConcurrentBatches > 1 && !cfg.Unordered {\n\t\treturn fmt.Errorf(\"redis: AutoPipelineOptions.MaxConcurrentBatches=%d requires Unordered:true \"+\n\t\t\t\"(parallel batches do not preserve command ordering); set Unordered:true to allow it, \"+\n\t\t\t\"or keep MaxConcurrentBatches=1 for an ordered stream\", cfg.MaxConcurrentBatches)\n\t}\n\t// Reject obviously-wrong negatives so a typo surfaces at construction rather\n\t// than being silently coerced to a default. Zero is allowed and means \"use\n\t// the default\" (MaxBatchSize) or \"no delay\" (MaxFlushDelay).\n\tif cfg.MaxBatchSize < 0 {\n\t\treturn fmt.Errorf(\"redis: AutoPipelineOptions.MaxBatchSize=%d must be >= 0\", cfg.MaxBatchSize)\n\t}\n\tif cfg.MaxBatchBytes < 0 {\n\t\treturn fmt.Errorf(\"redis: AutoPipelineOptions.MaxBatchBytes=%d must be >= 0\", cfg.MaxBatchBytes)\n\t}\n\tif cfg.MaxConcurrentBatches < 0 {\n\t\treturn fmt.Errorf(\"redis: AutoPipelineOptions.MaxConcurrentBatches=%d must be >= 0\", cfg.MaxConcurrentBatches)\n\t}\n\tif cfg.MaxFlushDelay < 0 {\n\t\treturn fmt.Errorf(\"redis: AutoPipelineOptions.MaxFlushDelay=%s must be >= 0\", cfg.MaxFlushDelay)\n\t}\n\tif cfg.NumShards < 0 {\n\t\treturn fmt.Errorf(\"redis: AutoPipelineOptions.NumShards=%d must be >= 0\", cfg.NumShards)\n\t}\n\tif cfg.AdaptiveDelay && cfg.MaxFlushDelay <= 0 {\n\t\treturn fmt.Errorf(\"redis: AutoPipelineOptions.AdaptiveDelay requires MaxFlushDelay > 0 \" +\n\t\t\t\"(adaptive delay scales MaxFlushDelay by queue fill; with no MaxFlushDelay it would \" +\n\t\t\t\"silently disable batch accumulation entirely)\")\n\t}","sourceCodeStart":207,"sourceCodeEnd":243,"githubUrl":"https://github.com/go-redis/redis/blob/36d97525cd8076aed67cddf54778e9ea84550929/autopipeline.go#L207-L243","documentation":"Returned by AutoPipelineOptions.Validate when MaxBatchSize is negative. Zero is allowed (meaning use the default batch size); negative values are rejected as typos rather than silently coerced. Validate runs lazily on the first AutoPipeline/AsyncAutoPipeline getter.","triggerScenarios":"Setting AutoPipelineOptions.MaxBatchSize to a negative number (e.g. -1 from an uninitialized/overflowing config value, or a sign error). Loading config where a missing value deserializes to a negative sentinel.","commonSituations":"Config parsing bugs that produce negatives. Arithmetic that underflows into a negative. Using -1 as an 'unlimited' sentinel when zero is the documented 'use default' value.","solutions":["Set MaxBatchSize to 0 (use the default) or a positive integer.","If you intended 'no cap', use 0, not a negative number.","Validate config values at load time before passing to AutoPipelineOptions."],"exampleFix":"// before\ncfg := &redis.AutoPipelineOptions{MaxBatchSize: -1}\n// cfg.Validate() => error\n\n// after — 0 means use default, or set an explicit positive cap\ncfg := &redis.AutoPipelineOptions{MaxBatchSize: 0}\n// or\ncfg := &redis.AutoPipelineOptions{MaxBatchSize: 500}","handlingStrategy":"validation","validationCode":"func sanitizeBatchSize(n int) int {\n    if n < 0 {\n        return 0 // use default instead of an invalid negative\n    }\n    return n\n}","typeGuard":null,"tryCatchPattern":"if err := cfg.Validate(); err != nil {\n    if strings.Contains(err.Error(), \"MaxBatchSize\") {\n        cfg.MaxBatchSize = 0 // reset to default\n    }\n}","preventionTips":["Use 0 for 'use default' MaxBatchSize, never a negative.","Validate config values at load time before constructing AutoPipelineOptions.","Clamp parsed config values to >= 0."],"tags":["autopipeline","validation","configuration","value-error"],"analyzedSha":"36d97525cd8076aed67cddf54778e9ea84550929","analyzedAt":"2026-08-06T01:08:27.376Z","schemaVersion":2}