apache/beam · error
Unexpected aggregate type: %v
Error message
Unexpected aggregate type: %v
What it means
FullType.New builds the typed tree for pipeline data types and panics when an Aggregate-class reflect.Type is neither an array, slice, nor other handled aggregate kind. It means New was handed a type classified as Container/aggregate whose Go kind is not one it can decompose into element components.
Source
Thrown at sdks/go/pkg/beam/core/typex/fulltype.go:121
func New(t reflect.Type, components ...FullType) FullType {
checkTypesNotNil(components)
class := ClassOf(t)
switch class {
case Concrete, Universal:
return &tree{class, t, nil}
case Container:
switch t.Kind() {
case reflect.Slice:
if len(components) == 0 {
// For elements without sub components, we just create with the type, this handles vanilla slices.
// We include the child type as a component for convenience.
return &tree{class, t, []FullType{New(t.Elem())}}
}
// For elements which themselves have components, we need to go deeper.
return &tree{class, t, []FullType{New(t.Elem(), components[0].Components()...)}}
default:
panic(fmt.Sprintf("Unexpected aggregate type: %v", t))
}
case Composite:
switch t {
case KVType:
if len(components) != 2 {
panic(fmt.Sprintf("Invalid number of components for KV: %v, %v", t, components))
}
if isAnyNonKVAndNonWindowedComposite(components) {
panic(fmt.Sprintf("Invalid to nest composite composites inside KV: %v, %v", t, components))
}
return &tree{class, t, components}
case WindowedValueType:
if len(components) != 1 {
panic("Invalid number of components for WindowedValue")
}
if components[0].Type() == WindowedValueType {
panic("Invalid to nest WindowedValue")
}View on GitHub (pinned to 12126d8942)
Solutions
- Let the SDK derive classes automatically; call typex.New(reflect.TypeOf(x)) without forcing a class.
- Use standard slice/array types for aggregations rather than custom kinds.
- Check that any custom class computation (e.g. Container) matches the actual reflect kind.
Example fix
// before
ft := typex.New(typex.Container, reflect.TypeOf(42)) // class/kind mismatch panics
// after
ft := typex.New(reflect.TypeOf([]int{})) Defensive patterns
Strategy: validation
Validate before calling
if t.Kind() != reflect.Slice && t.Kind() != reflect.Array {
return fmt.Errorf("expected aggregate slice/array type, got %v", t.Kind())
} Type guard
func isSliceOrArray(t reflect.Type) bool {
return t.Kind() == reflect.Slice || t.Kind() == reflect.Array
} Prevention
- Call typex.New with the reflect.Type only and let the SDK compute the class.
- Avoid forcing class parameters that may disagree with the underlying kind.
When it happens
Trigger: Calling typex.New (directly or via GroupByKey, CoGroupByKey, CombinePerKey, CombineGlobally, Flatten, Prefix) with an aggregate-classed type whose reflect kind is not slice/array/map-chan-handled, e.g. via an incorrect class parameter or exotic types.
Common situations: Hand-constructing FullType trees with mismatched class/kind pairs; custom graph builders classifying types incorrectly before calling New; SDK bugs with unusual reflect kinds.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- invalid Class value: %v
- Invalid number of components for KV: %v, %v
- Invalid to nest composite composites inside KV: %v, %v
- Invalid number of components for WindowedValue
- Invalid to nest WindowedValue
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/85f20b1e2ac59d9c.
Report an issue: GitHub.