{"record":{"id":"856c5f2e8a54fd9e","repo":"apache/beam","slug":"unexpected-aggregate-v-only-slices-allowed","errorCode":null,"errorMessage":"unexpected aggregate %v, only slices allowed","messagePattern":"unexpected aggregate (.+?), only slices allowed","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/typex/fulltype.go","lineNumber":427,"sourceCode":"\nfunc substitute(t FullType, m map[string]reflect.Type) (FullType, error) {\n\tswitch t.Class() {\n\tcase Universal:\n\t\tname := t.Type().Name()\n\t\trepl, ok := m[name]\n\t\tif !ok {\n\t\t\treturn nil, errors.Errorf(\"substituting type %v: type not bound\", name)\n\t\t}\n\t\treturn New(repl), nil\n\tcase Container:\n\t\tcomp, err := substituteList(t.Components(), m)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif IsList(t.Type()) {\n\t\t\treturn New(reflect.SliceOf(comp[0].Type()), comp...), nil\n\t\t}\n\t\treturn nil, errors.Errorf(\"unexpected aggregate %v, only slices allowed\", t)\n\tcase Composite:\n\t\tcomp, err := substituteList(t.Components(), m)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn New(t.Type(), comp...), nil\n\n\tdefault:\n\t\treturn t, nil\n\t}\n}\n\nfunc substituteList(list []FullType, m map[string]reflect.Type) ([]FullType, error) {\n\tvar ret []FullType\n\tfor _, elm := range list {\n\t\trepl, err := substitute(elm, m)\n\t\tif err != nil {\n\t\t\treturn nil, err","sourceCodeStart":409,"sourceCodeEnd":445,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/typex/fulltype.go#L409-L445","documentation":"During typex.Substitute, an Aggregate type whose underlying Go type is not a slice cannot be reconstructed from its substituted components: only reflect.Slice types can be rebuilt with reflect.SliceOf. Any other aggregate kind triggers this error.","triggerScenarios":"Substituting a FullType containing an Aggregate node whose t.Type() is an array, map, struct, or other non-slice composite, with variable components — e.g. an aggregate built from [2]T or map[string]T passed through Substitute.","commonSituations":"Users construct FullTypes with typex.New over array or map Go types containing type variables and then run Substitute; the Beam type system's substitution only supports slice-shaped aggregates, so pipelines using array-typed variables with generic coders hit this.","solutions":["Convert the aggregate to a slice type (e.g. use []T instead of [N]T) in your Fn signature or FullType construction.","If a map is intended, model it with typex.Container/map semantics rather than an Aggregate node.","Avoid substituting types with free variables inside array aggregates — bind to a fully concrete type instead.","Check the %v in the message for the offending aggregate type to confirm which declaration to change."],"exampleFix":"// before\ntypex.New(reflect.ArrayOf(2, typex.T.Type())) // array aggregate\n\n// after\ntypex.New(reflect.SliceOf(typex.T.Type())) // slice aggregate","handlingStrategy":"type-guard","validationCode":"func substitutableAggregate(t typex.FullType) bool {\n    return t.Class() != typex.Aggregate || typex.IsList(t.Type())\n}","typeGuard":"func isSliceAggregate(t typex.FullType) bool {\n    return t.Class() == typex.Aggregate && t.Type().Kind() == reflect.Slice\n}","tryCatchPattern":"out, err := typex.Substitute(t, m)\nif err != nil && strings.Contains(err.Error(), \"only slices allowed\") {\n    return fmt.Errorf(\"use slice-based types for generic aggregates: %w\", err)\n}","preventionTips":["Prefer slice types ([]T) over fixed-size arrays ([N]T) in generic DoFn signatures.","Do not embed type variables inside array or struct aggregates that will be substituted.","Keep type variables in Container or Universal positions, which Substitute fully supports.","If you need maps or structs with variables, bind them to concrete types first instead of substituting."],"tags":["go","apache-beam","type-substitution","unsupported"],"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"}