{"record":{"id":"fe526a9cb178c78e","repo":"apache/beam","slug":"batch-sizerprimitive-cannot-size-value-of-type-t","errorCode":null,"errorMessage":"batch: sizerPrimitive cannot size value of type %T","messagePattern":"batch: sizerPrimitive cannot size value of type %T","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/transforms/batch/batch.go","lineNumber":480,"sourceCode":"\t\tpanic(err)\n\t}\n\tif setBool {\n\t\tfn.Buffering.Clear(tp)\n\t\tif err := fn.TimerSet.Clear(sp); err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t}\n}\n\nfunc sizeOf(kind int32, v any) int64 {\n\tswitch kind {\n\tcase sizerNone:\n\t\treturn 0\n\tcase sizerPrimitive:\n\t\tif size, ok := defaultElementByteSize(v); ok {\n\t\t\treturn size\n\t\t}\n\t\tpanic(fmt.Sprintf(\"batch: sizerPrimitive cannot size value of type %T\", v))\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"batch: unknown sizer kind %d\", kind))\n\t}\n}\n\n// wrapShardedKeyFn maps KV<K, V> → KV<ShardedKey[K], V>.\ntype wrapShardedKeyFn[K any] struct{}\n\nfunc (*wrapShardedKeyFn[K]) ProcessElement(\n\tkey K, value typex.V, emit func(ShardedKey[K], typex.V),\n) {\n\temit(ShardedKey[K]{Key: key, ShardID: makeShardID()}, value)\n}\n\nvar (\n\tworkerUUIDOnce sync.Once\n\tworkerUUIDVal  [16]byte\n\tshardCounter   atomic.Uint64","sourceCodeStart":462,"sourceCodeEnd":498,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/transforms/batch/batch.go#L462-L498","documentation":"sizeOf with sizerPrimitive estimates element size via defaultElementByteSize, which only knows Beam's built-in primitive types. If the element is a custom Go type not covered by the defaults, the transform panics because it cannot compute a byte size for batching by BatchSizeBytes.","triggerScenarios":"Using beamx/batch with a primitive (default) sizer on a PCollection whose element type is a custom struct or otherwise unsupported type, with BatchSizeBytes configured, processed in ProcessElement.","commonSituations":"Developers batch custom structs without registering a coder-backed size or switching to a custom Sizer; often after changing the element type from primitives to structs.","solutions":["Provide a custom sizer for the element type instead of the default primitive sizer.","Switch the element to a supported primitive type or encode to bytes (e.g. []byte) before batching.","Set size accounting by count only (omit BatchSizeBytes) if byte sizing is not essential.","Check Beam's defaultElementByteSize supported types and align your schema."],"exampleFix":"// before\nbeam.ParDo(s, &batchFn[K, V]{Sizer: batch.SizerPrimitive, BatchSizeBytes: 1 << 20}, in) // V is a custom struct\n// after\nbeam.ParDo(s, &batchFn[K, V]{Sizer: mySizerFunc, BatchSizeBytes: 1 << 20}, in) // custom sizer handles V","handlingStrategy":"validation","validationCode":"// Before configuring byte-size batching, ensure the sizer can handle V\nvar v V\nif !canDefaultSize(v) { // struct types usually cannot\n\t// use a custom sizer instead of sizerPrimitive\n}\nfunc canDefaultSize(v any) bool {\n\tswitch v.(type) {\n\tcase int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64,\n\t\tfloat32, float64, string, bool, []byte:\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}","typeGuard":"func isPrimitiveSizable(v any) bool {\n\tswitch v.(type) {\n\tcase int, int64, uint64, float32, float64, string, bool, []byte:\n\t\treturn true\n\t}\n\treturn false\n}","tryCatchPattern":null,"preventionTips":["Use a custom sizer for struct element types","Only set BatchSizeBytes with primitive-sized collections","Check defaultElementByteSize support before enabling byte sizing"],"tags":["go","apache-beam","sizing","panic"],"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"}