{"record":{"id":"4bd679ff0b68a267","repo":"apache/beam","slug":"failed-to-optimize-addinput-for-combiner-v-failed-to-infer-4bd679","errorCode":null,"errorMessage":"Failed to optimize AddInput for combiner %v. Failed to infer types","messagePattern":"Failed to optimize AddInput for combiner (.+?)\\. Failed to infer types","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/register/register.tmpl","lineNumber":442,"sourceCode":"\t\t\t\treturn fn.(addInput2x2[T0, T2]).AddInput(a0, a1)\n\t\t\t})\n\t\t}\n    } else if _, ok := accum.(addInput2x1[T0, T2]); ok {\n        caller := func(fn any) reflectx.Func {\n            f := fn.(func(T0, T2) T0)\n            return &caller2x1[T0, T2, T0]{fn: f}\n        }\n\t\treflectx.RegisterFunc(reflect.TypeOf((*func(T0, T2) T0)(nil)).Elem(), caller)\n\n        addInputWrapper = func(fn any) reflectx.Func {\n\t\t\treturn reflectx.MakeFunc(func(a0 T0, a1 T2) T0 {\n\t\t\t\treturn fn.(addInput2x1[T0, T2]).AddInput(a0, a1)\n\t\t\t})\n\t\t}\n    } {{end}}\n\n    if m := accumVal.MethodByName(\"AddInput\"); m.IsValid() && addInputWrapper == nil {\n        panic(fmt.Sprintf(\"Failed to optimize AddInput for combiner %v. Failed to infer types\", accum))\n    }\n\n    var extractOutputWrapper func(fn any) reflectx.Func\n    if _, ok := accum.(extractOutput1x2[T0, T0]); ok {\n        caller := func(fn any) reflectx.Func {\n            f := fn.(func(T0) (T0, error))\n            return &caller1x2[T0, T0, error]{fn: f}\n        }\n\t\treflectx.RegisterFunc(reflect.TypeOf((*func(T0) (T0, error))(nil)).Elem(), caller)\n\n        extractOutputWrapper = func(fn any) reflectx.Func {\n\t\t\treturn reflectx.MakeFunc(func(a0 T0) (T0, error) {\n\t\t\t\treturn fn.(extractOutput1x2[T0, T0]).ExtractOutput(a0)\n\t\t\t})\n\t\t}\n    } else if _, ok := accum.(extractOutput1x1[T0, T0]); ok {\n        caller := func(fn any) reflectx.Func {\n            f := fn.(func(T0) T0)","sourceCodeStart":424,"sourceCodeEnd":460,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/register/register.tmpl#L424-L460","documentation":"This panic comes from Apache Beam Go SDK's generated combiner registration code (register.tmpl). When a combiner's accumulator type exposes an AddInput method, the generator tries to specialize a fast, type-safe wrapper for it; if it cannot infer the accumulator/input types from known signatures (e.g. AddInput1x1, AddInput2x1, etc.), it panics instead of silently falling back. It signals that the user's combiner type does not match any registered template instantiation.","triggerScenarios":"Registering a combiner via beam.Combine with an accumulator type that has an AddInput method whose signature does not match any generated wrapper variant, so the generated specialization loop leaves addInputWrapper nil while accumVal.MethodByName(\"AddInput\") is valid.","commonSituations":"Defining a custom combiner with a hand-written AddInput method using unsupported types or arity (e.g. three inputs, custom structs, variadic args), or changing a combiner's accumulator type after upgrading Beam so it no longer matches generated variants.","solutions":["Change the accumulator's AddInput method signature to one of the supported generated arities/types (e.g. AddInput(T0) or AddInput(T0, T1) with registered types).","Remove the explicit AddInput method from the accumulator so the SDK uses the generic reflection path instead of panicking.","Use the provided combiner helpers (beam.CombineWithContext with perf.CombineFn pattern) so the SDK infers types via RegisterDoFn/RegisterCombiner.","Ensure all custom types in the signature are registered with register.Function/Type so template inference succeeds."],"exampleFix":"// before\ntype avgAcc struct{ sum int64; n int }\nfunc (a *avgAcc) AddInput(v ...int64) { ... } // unsupported variadic\n\n// after\ntype avgAcc struct{ sum int64; n int }\nfunc (a *avgAcc) AddInput(v int64) { a.sum += v; a.n++ }","handlingStrategy":"validation","validationCode":"// Before registering the combiner, check the AddInput method matches a supported arity\nm := reflect.ValueOf(myAcc{}).MethodByName(\"AddInput\")\nif m.IsValid() {\n    t := m.Type()\n    if t.NumIn() > 2 || t.IsVariadic() {\n        panic(\"AddInput signature not supported by beam codegen; reduce arity / remove variadic\")\n    }\n}","typeGuard":"func hasSupportedAddInput(acc any) bool {\n    m := reflect.ValueOf(acc).MethodByName(\"AddInput\")\n    if !m.IsValid() { return true }\n    t := m.Type()\n    return !t.IsVariadic() && t.NumIn() <= 2\n}","tryCatchPattern":"// Go panics cannot be caught per-call site idiomatically in library use;\n// validate at startup:\nfunc init() {\n    if !hasSupportedAddInput(myAcc{}) {\n        panic(\"combiner AddInput signature unsupported; fix before running pipeline\")\n    }\n}","preventionTips":["Keep AddInput to 1 or 2 typed parameters with no variadics.","Register all custom types with register.Type/register.Function.","Avoid renaming or reshaping accumulator methods when upgrading Beam.","Run a small unit pipeline that registers the combiner before production runs."],"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-14T11:17:12.474Z"}