{"record":{"id":"8aa973907de294e1","repo":"apache/beam","slug":"params-at-least-one-of-batchsize-or-batchsizebytes-must-be-0","errorCode":null,"errorMessage":"Params: at least one of BatchSize or BatchSizeBytes must be > 0","messagePattern":"Params: at least one of BatchSize or BatchSizeBytes must be > 0","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/transforms/batch/batch.go","lineNumber":189,"sourceCode":"\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\n// codecCache keeps a per-value-type ElementEncoder/Decoder pair.\ntype codecCache struct {\n\tonce sync.Once\n\tenc  beam.ElementEncoder\n\tdec  beam.ElementDecoder\n}","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/transforms/batch/batch.go#L171-L207","documentation":"Error returned by batch.Params.validate (used by GroupIntoBatches and GroupIntoBatchesWithShardedKey) when both BatchSize and BatchSizeBytes are zero (and neither is negative, which is checked earlier). With both triggers disabled the batch transform would never emit, so at least one positive bound is mandatory.","triggerScenarios":"Passing batch.Params{} or Params with both BatchSize and BatchSizeBytes equal to 0 to GroupIntoBatches / GroupIntoBatchesWithShardedKey — e.g. a zero-value struct with only MaxBufferingDuration set.","commonSituations":"Forgetting to fill in Params (using the zero value), relying solely on MaxBufferingDuration thinking it alone triggers batching, or defaults read as 0 from an empty config.","solutions":["Set BatchSize to a positive value (e.g. Params{BatchSize: 100})","Or set BatchSizeBytes to a positive byte limit (e.g. Params{BatchSizeBytes: 1 << 20})","Or set both for combined count/byte batching","Check config loading so defaults actually populate a nonzero size"],"exampleFix":"// before\np := batch.Params{MaxBufferingDuration: 10 * time.Second} // both sizes 0\n// after\np := batch.Params{BatchSize: 100, MaxBufferingDuration: 10 * time.Second}","handlingStrategy":"validation","validationCode":"if p.BatchSize == 0 && p.BatchSizeBytes == 0 { return errors.New(\"set BatchSize or BatchSizeBytes\") } // before calling GroupIntoBatches","typeGuard":null,"tryCatchPattern":"if err := p.Validate(); err != nil {\n    return fmt.Errorf(\"invalid batch params: %w\", err)\n}","preventionTips":["Never pass a zero-value batch.Params struct","Remember MaxBufferingDuration alone does not satisfy batching","Provide defaults from config: BatchSize or BatchSizeBytes must be > 0","Write a constructor/helper that enforces at least one size is set"],"tags":["go","batching","validation","config"],"backgroundTag":"missing-required-config-field","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"}