{"record":{"id":"985151915d5a4c00","repo":"apache/beam","slug":"failed-to-optimize-extractoutput-for-combiner-v-failed-to-985151","errorCode":null,"errorMessage":"Failed to optimize ExtractOutput for combiner %v. Failed to infer types","messagePattern":"Failed to optimize ExtractOutput for combiner (.+?)\\. Failed to infer types","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/register/register.tmpl","lineNumber":521,"sourceCode":"\t\t\t\treturn fn.(extractOutput1x2[T0, T2]).ExtractOutput(a0)\n\t\t\t})\n\t\t}\n    } else if _, ok := accum.(extractOutput1x1[T0, T2]); ok {\n        caller := func(fn any) reflectx.Func {\n            f := fn.(func(T0) T2)\n            return &caller1x1[T0, T2]{fn: f}\n        }\n\t\treflectx.RegisterFunc(reflect.TypeOf((*func(T0) T2)(nil)).Elem(), caller)\n\n        extractOutputWrapper = func(fn any) reflectx.Func {\n\t\t\treturn reflectx.MakeFunc(func(a0 T0) T2 {\n\t\t\t\treturn fn.(extractOutput1x1[T0, T2]).ExtractOutput(a0)\n\t\t\t})\n\t\t}\n    } {{end}}\n\n    if m := accumVal.MethodByName(\"ExtractOutput\"); m.IsValid() && extractOutputWrapper == nil {\n        panic(fmt.Sprintf(\"Failed to optimize ExtractOutput for combiner %v. Failed to infer types\", accum))\n    }\n\n\twrapperFn := func(fn any) map[string]reflectx.Func {\n\t\tm := map[string]reflectx.Func{}\n\t\tif mergeAccumulatorsWrapper != nil {\n\t\t\tm[\"MergeAccumulators\"] = mergeAccumulatorsWrapper(fn)\n\t\t}\n\t\tif createAccumulatorWrapper != nil {\n\t\t\tm[\"CreateAccumulator\"] = createAccumulatorWrapper(fn)\n\t\t}\n\t\tif addInputWrapper != nil {\n\t\t\tm[\"AddInput\"] = addInputWrapper(fn)\n\t\t}\n\t\tif extractOutputWrapper != nil {\n\t\t\tm[\"ExtractOutput\"] = extractOutputWrapper(fn)\n\t\t}\n\n\t\treturn m","sourceCodeStart":503,"sourceCodeEnd":539,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/register/register.tmpl#L503-L539","documentation":"This panic is raised by Apache Beam Go SDK's generated combiner wrapper code when the accumulator type has an ExtractOutput method but no type-specialized wrapper could be generated for it. The template only instantiates wrappers for a fixed set of ExtractOutput signatures; an unrecognized signature leaves extractOutputWrapper nil and the code panics rather than producing a broken combiner.","triggerScenarios":"Using beam.Combine with a combiner whose accumulator defines ExtractOutput with a return type or arity that does not match any generated variant (e.g. ExtractOutput returning three values or unregistered custom types), triggering the MethodByName(\"ExtractOutput\") check with a nil wrapper.","commonSituations":"Custom combiners written against an older Beam template shape, accumulator methods returning multiple values, or using types not registered with the SDK so codegen cannot infer them.","solutions":["Adjust ExtractOutput to a supported signature (e.g. func ExtractOutput() T0 or (T0, error)) matching a generated wrapper variant.","Remove the explicit ExtractOutput method and let the SDK use reflection-based defaults.","Register custom types with register.Type / register.Function so type inference succeeds.","Pin compatible Beam SDK version matching your combiner's method shapes."],"exampleFix":"// before\nfunc (a *acc) ExtractOutput() (int64, int, error) { return a.sum, a.n, nil }\n\n// after\nfunc (a *acc) ExtractOutput() int64 { return a.sum / int64(a.n) }","handlingStrategy":"validation","validationCode":"// Verify ExtractOutput returns at most one value plus optional error\nm := reflect.ValueOf(myAcc{}).MethodByName(\"ExtractOutput\")\nif m.IsValid() {\n    t := m.Type()\n    if t.NumOut() > 2 {\n        panic(\"ExtractOutput must return (T) or (T, error)\")\n    }\n}","typeGuard":"func hasSupportedExtractOutput(acc any) bool {\n    m := reflect.ValueOf(acc).MethodByName(\"ExtractOutput\")\n    if !m.IsValid() { return true }\n    t := m.Type()\n    return t.NumOut() == 1 || (t.NumOut() == 2 && t.Out(1) == reflect.TypeOf((*error)(nil)).Elem())\n}","tryCatchPattern":"// Validate combiner shape at process start\nfunc init() {\n    if !hasSupportedExtractOutput(myAcc{}) {\n        panic(\"combiner ExtractOutput signature unsupported by beam codegen\")\n    }\n}","preventionTips":["Return a single value (optionally with error) from ExtractOutput.","Register accumulator types so codegen can infer them.","Test combiner registration in a tiny pipeline before deploying.","Match method signatures to the Beam version's documented combiner interface."],"tags":["go","beam","combiner","codegen"],"backgroundTag":"internal-invariant-violation","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}