apache/beam · error
unable to infer CombineFn accumulator coder
Error message
unable to infer CombineFn accumulator coder
What it means
TryCombinePerKey tries to infer the coder for the CombineFn's accumulator type — the return type of MergeAccumulators — by calling inferCoder. If that inference fails (for example the accumulator type is an interface with no coder registered), the error is wrapped as "unable to infer CombineFn accumulator coder" and the combine edge is not created. This happens before any data is processed, at pipeline construction time.
Source
Thrown at sdks/go/pkg/beam/combine.go:83
return PCollection{}, addCombinePerKeyCtx(errors.New("combine does not support side inputs"), s)
}
col, err = TryGroupByKey(s, col)
if err != nil {
return PCollection{}, addCombinePerKeyCtx(err, s)
}
fn, err := graph.NewCombineFn(combinefn)
if err != nil {
return PCollection{}, addCombinePerKeyCtx(err, s)
}
// This seems like the best place to infer the accumulator coder type, unless
// it's a universal type.
// We can get the fulltype from the return value of the mergeAccumulatorFn
// TODO(lostluck): 2018/05/28 Correctly infer universal type coder if necessary.
accumCoder, err := inferCoder(typex.New(fn.MergeAccumulatorsFn().Ret[0].T))
if err != nil {
wrapped := errors.Wrap(err, "unable to infer CombineFn accumulator coder")
return PCollection{}, addCombinePerKeyCtx(wrapped, s)
}
edge, err := graph.NewCombine(s.real, s.scope, fn, col.n, accumCoder, typedefs)
if err != nil {
return PCollection{}, addCombinePerKeyCtx(err, s)
}
ret := PCollection{edge.Output[0].To}
ret.SetCoder(NewCoder(ret.Type()))
return ret, nil
}
View on GitHub (pinned to 12126d8942)
Solutions
- Make the accumulator a concrete exported struct type with JSON-serializable fields.
- Implement MarshalJSON/UnmarshalJSON on the accumulator type so the default JSON coder applies.
- Supply an explicit accumulator coder: use combine.TryCombinePerKey with coder.NewCustomCoder(...) for the accumulator type (see the accumCoder argument to graph.NewCombine).
- Read the wrapped cause to see whether it is error 4805 (interface without coder) or 4806 (invalid coder) and fix accordingly.
- Move the failing per-key Combine into a global beam.Combine with an explicit coder if per-key inference remains problematic.
Example fix
// before
func (fn *MyCombine) MergeAccumulators(a, b MyAcc) MyAcc { ... } // MyAcc is an interface
// after
type myAcc struct { Sum int } // concrete accumulator
func (fn *MyCombine) MergeAccumulators(a, b myAcc) myAcc { return myAcc{a.Sum + b.Sum} } Defensive patterns
Strategy: validation
Validate before calling
accumT := fn.MergeAccumulatorsFn().Ret[0].T
if accumT.Kind() == reflect.Interface && !accumT.Implements(jsonCoderType) {
return fmt.Errorf("CombineFn accumulator type %v needs a concrete type or explicit coder", accumT)
} Type guard
func hasValidAccumulatorCoder(fn *combine.CombineFn) bool {
t := fn.MergeAccumulatorsFn().Ret[0].T
return t != nil && (t.Kind() != reflect.Interface || t.Implements(jsonCoderType))
} Try / catch
accumCoder, err := inferCoder(typex.New(fn.MergeAccumulatorsFn().Ret[0].T))
if err != nil {
return PCollection{}, addCombinePerKeyCtx(errors.Wrap(err, "unable to infer CombineFn accumulator coder"), s)
} Prevention
- Define CombineFn accumulators as concrete exported structs.
- Register an accumulator coder explicitly when using custom accumulator types.
- Unit-test MergeAccumulators' return type with inferCoder/beam.NewCoder early.
- Keep accumulator fields JSON-serializable.
When it happens
Trigger: Calling beam.CombinePerKey / combine.TryCombine (or TryCombinePerKey) with a CombineFn whose MergeAccumulators return type is an interface type that does not implement json.Marshaler, or whose accumulator type otherwise has no registered coder.
Common situations: Custom CombineFns whose accumulator is map[string]interface{} or a custom interface; combiners written generically over accumulator types; upgrading Beam where accumulator coder inference became stricter.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- inferCoder failed: interface type %v has no coder registered
- invalid status for precombine %v: %v
- invalid status for combine merge %v: %v
- invalid status for combine extract %v: %v
- invalid status for combine convert %v: %v
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/df7dcbc15755a51d.
Report an issue: GitHub.