{"record":{"id":"85f20b1e2ac59d9c","repo":"apache/beam","slug":"unexpected-aggregate-type-v","errorCode":null,"errorMessage":"Unexpected aggregate type: %v","messagePattern":"Unexpected aggregate type: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/typex/fulltype.go","lineNumber":121,"sourceCode":"func New(t reflect.Type, components ...FullType) FullType {\n\tcheckTypesNotNil(components)\n\n\tclass := ClassOf(t)\n\tswitch class {\n\tcase Concrete, Universal:\n\t\treturn &tree{class, t, nil}\n\tcase Container:\n\t\tswitch t.Kind() {\n\t\tcase reflect.Slice:\n\t\t\tif len(components) == 0 {\n\t\t\t\t// For elements without sub components, we just create with the type, this handles vanilla slices.\n\t\t\t\t// We include the child type as a component for convenience.\n\t\t\t\treturn &tree{class, t, []FullType{New(t.Elem())}}\n\t\t\t}\n\t\t\t// For elements which themselves have components, we need to go deeper.\n\t\t\treturn &tree{class, t, []FullType{New(t.Elem(), components[0].Components()...)}}\n\t\tdefault:\n\t\t\tpanic(fmt.Sprintf(\"Unexpected aggregate type: %v\", t))\n\t\t}\n\tcase Composite:\n\t\tswitch t {\n\t\tcase KVType:\n\t\t\tif len(components) != 2 {\n\t\t\t\tpanic(fmt.Sprintf(\"Invalid number of components for KV: %v, %v\", t, components))\n\t\t\t}\n\t\t\tif isAnyNonKVAndNonWindowedComposite(components) {\n\t\t\t\tpanic(fmt.Sprintf(\"Invalid to nest composite composites inside KV: %v, %v\", t, components))\n\t\t\t}\n\t\t\treturn &tree{class, t, components}\n\t\tcase WindowedValueType:\n\t\t\tif len(components) != 1 {\n\t\t\t\tpanic(\"Invalid number of components for WindowedValue\")\n\t\t\t}\n\t\t\tif components[0].Type() == WindowedValueType {\n\t\t\t\tpanic(\"Invalid to nest WindowedValue\")\n\t\t\t}","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/typex/fulltype.go#L103-L139","documentation":"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.","triggerScenarios":"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.","commonSituations":"Hand-constructing FullType trees with mismatched class/kind pairs; custom graph builders classifying types incorrectly before calling New; SDK bugs with unusual reflect kinds.","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."],"exampleFix":"// before\nft := typex.New(typex.Container, reflect.TypeOf(42)) // class/kind mismatch panics\n// after\nft := typex.New(reflect.TypeOf([]int{}))","handlingStrategy":"validation","validationCode":"if t.Kind() != reflect.Slice && t.Kind() != reflect.Array {\n\treturn fmt.Errorf(\"expected aggregate slice/array type, got %v\", t.Kind())\n}","typeGuard":"func isSliceOrArray(t reflect.Type) bool {\n\treturn t.Kind() == reflect.Slice || t.Kind() == reflect.Array\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["go","beam","typex","fulltype","panic"],"backgroundTag":"invalid-argument-value","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T21:17:11.552Z"}