{"record":{"id":"d7d1a0a9240f459b","repo":"apache/beam","slug":"params-batchsize-must-be-0-got-d","errorCode":null,"errorMessage":"Params.BatchSize must be >= 0; got %d","messagePattern":"Params\\.BatchSize must be >= 0; got (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/transforms/batch/batch.go","lineNumber":183,"sourceCode":"\t// batch is emitted as soon as it holds BatchSize elements. Zero\n\t// disables the count-based trigger.\n\tBatchSize int64\n\n\t// BatchSizeBytes is the target maximum cumulative byte size per\n\t// batch. A batch is emitted as soon as adding another element\n\t// would exceed BatchSizeBytes. Zero disables the byte-based\n\t// trigger.\n\tBatchSizeBytes int64\n\n\t// MaxBufferingDuration, when > 0, triggers emission of a partial\n\t// batch after this much processing time has elapsed since the\n\t// first element of the current batch was buffered.\n\tMaxBufferingDuration time.Duration\n}\n\nfunc (p Params) validate() error {\n\tif p.BatchSize < 0 {\n\t\treturn fmt.Errorf(\"Params.BatchSize must be >= 0; got %d\", p.BatchSize)\n\t}\n\tif p.BatchSizeBytes < 0 {\n\t\treturn fmt.Errorf(\"Params.BatchSizeBytes must be >= 0; got %d\", p.BatchSizeBytes)\n\t}\n\tif p.BatchSize == 0 && p.BatchSizeBytes == 0 {\n\t\treturn fmt.Errorf(\"Params: at least one of BatchSize or BatchSizeBytes must be > 0\")\n\t}\n\tif p.MaxBufferingDuration < 0 {\n\t\treturn fmt.Errorf(\"Params.MaxBufferingDuration must be >= 0; got %s\", p.MaxBufferingDuration)\n\t}\n\treturn nil\n}\n\nconst (\n\tsizerNone      int32 = 0\n\tsizerPrimitive int32 = 1\n)\n","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/transforms/batch/batch.go#L165-L201","documentation":"GroupIntoBatches validates its Params before building the transform: BatchSize counts elements per batch and must be non-negative. A negative value indicates a configuration bug and is rejected immediately.","triggerScenarios":"Constructing batch.Params{BatchSize: -1} (or any negative) and passing it to GroupIntoBatches or GroupIntoBatchesWithShardedKey, often from a computed or user-supplied value.","commonSituations":"BatchSize computed from a config variable that is negative or uninitialized via a signed type, off-by-one negation when deriving size from another value.","solutions":["Set BatchSize to a positive value, or 0 if BatchSizeBytes is used instead","Clamp/validate user- or config-supplied sizes before constructing Params: if n < 0 { n = 0 }","Use an unsigned or validated config source for batch sizing"],"exampleFix":"// before\np := batch.Params{BatchSize: cfg.Size} // may be -1\n// after\nsize := cfg.Size\nif size < 0 { size = 0 }\np := batch.Params{BatchSize: size}","handlingStrategy":"validation","validationCode":"if p.BatchSize < 0 { return errors.New(\"BatchSize must be >= 0\") } // before calling GroupIntoBatches","typeGuard":null,"tryCatchPattern":"if err := p.Validate(); err != nil { // or catch from GroupIntoBatches\n    return fmt.Errorf(\"invalid batch params: %w\", err)\n}","preventionTips":["Clamp computed sizes to >= 0 before building Params","Source batch sizes from unsigned or validated config","Call Params.validate-style checks at config load time","Use sane positive defaults"],"tags":["go","batching","validation","config"],"backgroundTag":"invalid-config-value","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}