{"record":{"id":"abf66161148884e6","repo":"apache/beam","slug":"groupintobatches-batchsizebytes-0-requires-value-type-v-to","errorCode":null,"errorMessage":"GroupIntoBatches: BatchSizeBytes > 0 requires value type %v to be a built-in primitive ([]byte, string, numeric, bool)","messagePattern":"GroupIntoBatches: BatchSizeBytes > 0 requires value type (.+?) to be a built-in primitive \\(\\[\\]byte, string, numeric, bool\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/transforms/batch/batch.go","lineNumber":601,"sourceCode":"\t\tpanic(fmt.Errorf(\n\t\t\t\"GroupIntoBatches: input PCollection must be KV-typed; got %v\", col.Type()))\n\t}\n\n\tkeyFT := col.Type().Components()[0]\n\tvalFT := col.Type().Components()[1]\n\n\tif !beam.NewCoder(keyFT).IsDeterministic() {\n\t\tpanic(fmt.Errorf(\n\t\t\t\"GroupIntoBatches: key coder for type %v is not deterministic. \"+\n\t\t\t\t\"Register a deterministic custom coder with \"+\n\t\t\t\t\"coder.RegisterDeterministicCoder, or use a deterministic key \"+\n\t\t\t\t\"type (string, []byte, bool, integer, float)\", keyFT.Type()))\n\t}\n\n\tsizerKind := sizerNone\n\tif params.BatchSizeBytes > 0 {\n\t\tif !isBuiltinSizeable(valFT.Type()) {\n\t\t\tpanic(fmt.Errorf(\n\t\t\t\t\"GroupIntoBatches: BatchSizeBytes > 0 requires value type %v \"+\n\t\t\t\t\t\"to be a built-in primitive ([]byte, string, numeric, bool)\",\n\t\t\t\tvalFT.Type()))\n\t\t}\n\t\tsizerKind = sizerPrimitive\n\t}\n\n\tallowedLatenessMs := int64(col.WindowingStrategy().AllowedLateness)\n\tvalueType := beam.EncodedType{T: valFT.Type()}\n\n\tif params.MaxBufferingDuration > 0 {\n\t\tfn := &groupIntoBatchesBufferedFn{\n\t\t\tBuffer:            state.MakeBagState[[]byte](\"batchBuffer\"),\n\t\t\tCount:             state.MakeValueState[int64](\"batchCount\"),\n\t\t\tByteSize:          state.MakeValueState[int64](\"batchBytes\"),\n\t\t\tTimerSet:          state.MakeValueState[bool](\"batchTimerSet\"),\n\t\t\tBuffering:         timers.InProcessingTime(\"batchBuffering\"),\n\t\t\tWindowEnd:         timers.InEventTime(\"batchWindowEnd\"),","sourceCodeStart":583,"sourceCodeEnd":619,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/transforms/batch/batch.go#L583-L619","documentation":"Byte-based batching (BatchSizeBytes > 0) needs each element's size, which the transform can only compute for built-in primitive value types via isBuiltinSizeable. Custom/complex value types have no sizer, so the transform panics. Use element-count batching or a primitive value type.","triggerScenarios":"Setting Params.BatchSizeBytes > 0 while the KV value type is a custom struct, slice of structs, or any type not covered by isBuiltinSizeable.","commonSituations":"Trying to cap batch bytes for protobuf messages or application structs; copying count-limited examples and only changing the limit field.","solutions":["Switch to BatchSize (count-based) instead of BatchSizeBytes","Change the value type to []byte, string, numeric, or bool","Pre-encode values to []byte before batching to enable byte-based sizing","Check isBuiltinSizeable-equivalent before setting BatchSizeBytes"],"exampleFix":"// before\nparams := batch.Params{BatchSizeBytes: 1 << 20} // values are custom structs\n// after\nparams := batch.Params{BatchSize: 500} // or emit []byte values","handlingStrategy":"validation","validationCode":"if params.BatchSizeBytes > 0 && !isPrimitiveValueType(reflect.TypeOf(MyVal{})) {\n    return errors.New(\"use BatchSize or primitive value types\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use BatchSize for custom value types","Pre-encode to []byte for byte limits","Document byte-limit constraints for pipeline authors"],"tags":["go","apache-beam","validation","byte-size"],"backgroundTag":"unsupported-operation","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"}