apache/beam · error

batch: sizerPrimitive cannot size value of type %T

Error message

batch: sizerPrimitive cannot size value of type %T

What it means

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.

Solutions

  1. Provide a custom sizer for the element type instead of the default primitive sizer.
  2. Switch the element to a supported primitive type or encode to bytes (e.g. []byte) before batching.
  3. Set size accounting by count only (omit BatchSizeBytes) if byte sizing is not essential.
  4. Check Beam's defaultElementByteSize supported types and align your schema.

Example fix

// before
beam.ParDo(s, &batchFn[K, V]{Sizer: batch.SizerPrimitive, BatchSizeBytes: 1 << 20}, in) // V is a custom struct
// after
beam.ParDo(s, &batchFn[K, V]{Sizer: mySizerFunc, BatchSizeBytes: 1 << 20}, in) // custom sizer handles V
Defensive patterns

Strategy: validation

Validate before calling

// Before configuring byte-size batching, ensure the sizer can handle V
var v V
if !canDefaultSize(v) { // struct types usually cannot
	// use a custom sizer instead of sizerPrimitive
}
func canDefaultSize(v any) bool {
	switch v.(type) {
	case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64,
		float32, float64, string, bool, []byte:
		return true
	default:
		return false
	}
}

Type guard

func isPrimitiveSizable(v any) bool {
	switch v.(type) {
	case int, int64, uint64, float32, float64, string, bool, []byte:
		return true
	}
	return false
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/fe526a9cb178c78e. Report an issue: GitHub.

Appendix: source

Thrown at sdks/go/pkg/beam/transforms/batch/batch.go:480

		panic(err)
	}
	if setBool {
		fn.Buffering.Clear(tp)
		if err := fn.TimerSet.Clear(sp); err != nil {
			panic(err)
		}
	}
}

func sizeOf(kind int32, v any) int64 {
	switch kind {
	case sizerNone:
		return 0
	case sizerPrimitive:
		if size, ok := defaultElementByteSize(v); ok {
			return size
		}
		panic(fmt.Sprintf("batch: sizerPrimitive cannot size value of type %T", v))
	default:
		panic(fmt.Sprintf("batch: unknown sizer kind %d", kind))
	}
}

// wrapShardedKeyFn maps KV<K, V> → KV<ShardedKey[K], V>.
type wrapShardedKeyFn[K any] struct{}

func (*wrapShardedKeyFn[K]) ProcessElement(
	key K, value typex.V, emit func(ShardedKey[K], typex.V),
) {
	emit(ShardedKey[K]{Key: key, ShardID: makeShardID()}, value)
}

var (
	workerUUIDOnce sync.Once
	workerUUIDVal  [16]byte
	shardCounter   atomic.Uint64

View on GitHub (pinned to 12126d8942)