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

  1. Make the accumulator a concrete exported struct type with JSON-serializable fields.
  2. Implement MarshalJSON/UnmarshalJSON on the accumulator type so the default JSON coder applies.
  3. Supply an explicit accumulator coder: use combine.TryCombinePerKey with coder.NewCustomCoder(...) for the accumulator type (see the accumCoder argument to graph.NewCombine).
  4. Read the wrapped cause to see whether it is error 4805 (interface without coder) or 4806 (invalid coder) and fix accordingly.
  5. 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

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


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/df7dcbc15755a51d. Report an issue: GitHub.