apache/beam · error
Failed to optimize ExtractOutput for combiner %v. Failed to
Error message
Failed to optimize ExtractOutput for combiner %v. Failed to infer types
What it means
Panicked from register.Combiner1/Combiner2 in register.go. The registration code tries to wrap ExtractOutput via extractOutput1x2[T0,T0] (ExtractOutput(T0) (T0, error)) or extractOutput1x1[T0,T0] (ExtractOutput(T0) T0). If the combiner exposes an ExtractOutput method (detected by MethodByName) that fits neither shape for the inferred types, no wrapper can be constructed and the library panics.
Source
Thrown at sdks/go/pkg/beam/register/register.go:7986
return fn.(extractOutput1x2[T0, T0]).ExtractOutput(a0)
})
}
} else if _, ok := accum.(extractOutput1x1[T0, T0]); ok {
caller := func(fn any) reflectx.Func {
f := fn.(func(T0) T0)
return &caller1x1[T0, T0]{fn: f}
}
reflectx.RegisterFunc(reflect.TypeOf((*func(T0) T0)(nil)).Elem(), caller)
extractOutputWrapper = func(fn any) reflectx.Func {
return reflectx.MakeFunc(func(a0 T0) T0 {
return fn.(extractOutput1x1[T0, T0]).ExtractOutput(a0)
})
}
}
if m := accumVal.MethodByName("ExtractOutput"); m.IsValid() && extractOutputWrapper == nil {
panic(fmt.Sprintf("Failed to optimize ExtractOutput for combiner %v. Failed to infer types", accum))
}
wrapperFn := func(fn any) map[string]reflectx.Func {
m := map[string]reflectx.Func{}
if mergeAccumulatorsWrapper != nil {
m["MergeAccumulators"] = mergeAccumulatorsWrapper(fn)
}
if createAccumulatorWrapper != nil {
m["CreateAccumulator"] = createAccumulatorWrapper(fn)
}
if addInputWrapper != nil {
m["AddInput"] = addInputWrapper(fn)
}
if extractOutputWrapper != nil {
m["ExtractOutput"] = extractOutputWrapper(fn)
}
return mView on GitHub (pinned to 12126d8942)
Solutions
- Make ExtractOutput match `func (c *C) ExtractOutput(accum T) T` or `func (c *C) ExtractOutput(accum T) (T, error)` for the type parameter used.
- If output type differs from accumulator type, register with Combiner2[AccumT, OutputT] and shape methods accordingly.
- Ensure ExtractOutput takes exactly one accumulator argument.
- Remove ExtractOutput if the accumulator itself is the output.
Example fix
// before
func (c *Sum) ExtractOutput(a *Stats) int { return a.total }
register.Combiner1[*Stats](&Sum{})
// after
func (c *Sum) ExtractOutput(a *Stats) (*Stats, error) { return a, nil }
register.Combiner1[*Stats](&Sum{}) Defensive patterns
Strategy: validation
Validate before calling
func validateExtractOutput[T0 any](c any) bool {
_, ok1 := c.(interface{ ExtractOutput(T0) T0 })
_, ok2 := c.(interface{ ExtractOutput(T0) (T0, error) })
return ok1 || ok2
}
// verify before register.Combiner1[T0](&c{}) Type guard
func hasTypedExtractOutput[T0 any](c any) bool {
_, ok1 := c.(interface{ ExtractOutput(T0) T0 })
_, ok2 := c.(interface{ ExtractOutput(T0) (T0, error) })
return ok1 || ok2
} Prevention
- Make ExtractOutput take one accumulator and return that same type (plus optional error).
- Use Combiner2 when the extracted output type differs from the accumulator type.
- Avoid returning multiple values from ExtractOutput beyond (T, error).
- Exercise the register call in tests so the panic appears at CI time.
When it happens
Trigger: register.Combiner1[T](&c{}) or Combiner2 where c.ExtractOutput's parameter or return type doesn't equal the inferred T0 — e.g. ExtractOutput(accum AccumT) OutputT with AccumT != OutputT under Combiner1, extra arguments, or returns types unsupported by the wrappers.
Common situations: Combiner producing a different output type than the accumulator (e.g. averaging accumulates [sum,count] and extracts a float) registered with Combiner1 instead of Combiner2; type parameter order mistakes in Combiner2; refactoring ExtractOutput to return multiple values.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Failed to optimize AddInput for combiner %v. Failed to infer
- panic(formatParDoError(dofn, len(ret), 3))
- panic(formatParDoError(dofn, len(ret), 4))
- panic(formatParDoError(dofn, len(ret), 5))
- panic(formatParDoError(dofn, len(ret), 6))
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/6b725ef2a13643c8.
Report an issue: GitHub.