apache/beam · error

Failed to optimize CreateAccumulator for combiner %v. Failed

Error message

Failed to optimize CreateAccumulator for combiner %v. Failed to infer types

What it means

This panic comes from Apache Beam Go's register.Combiner1 (or Combiner2) in register.go. When registering a CombineFn, the framework type-asserts the combiner against generic interfaces like createAccumulator0x1[T0]/createAccumulator0x2[T0] to build fast typed wrappers. If the combiner has a CreateAccumulator method (found via reflection) but it does not match either supported signature for the inferred type T0, no wrapper can be built and the library panics with this message rather than silently falling back to slow reflection.

Source

Thrown at sdks/go/pkg/beam/register/register.go:7924

			return reflectx.MakeFunc(func() (T0, error) {
				return fn.(createAccumulator0x2[T0]).CreateAccumulator()
			})
		}
	} else if _, ok := accum.(createAccumulator0x1[T0]); ok {
		caller := func(fn any) reflectx.Func {
			f := fn.(func() T0)
			return &caller0x1[T0]{fn: f}
		}
		reflectx.RegisterFunc(reflect.TypeOf((*func() T0)(nil)).Elem(), caller)

		createAccumulatorWrapper = func(fn any) reflectx.Func {
			return reflectx.MakeFunc(func() T0 {
				return fn.(createAccumulator0x1[T0]).CreateAccumulator()
			})
		}
	}
	if m := accumVal.MethodByName("CreateAccumulator"); m.IsValid() && createAccumulatorWrapper == nil {
		panic(fmt.Sprintf("Failed to optimize CreateAccumulator for combiner %v. Failed to infer types", accum))
	}

	var addInputWrapper func(fn any) reflectx.Func
	if _, ok := accum.(addInput2x2[T0, T0]); ok {
		caller := func(fn any) reflectx.Func {
			f := fn.(func(T0, T0) (T0, error))
			return &caller2x2[T0, T0, T0, error]{fn: f}
		}
		reflectx.RegisterFunc(reflect.TypeOf((*func(T0, T0) (T0, error))(nil)).Elem(), caller)

		addInputWrapper = func(fn any) reflectx.Func {
			return reflectx.MakeFunc(func(a0 T0, a1 T0) (T0, error) {
				return fn.(addInput2x2[T0, T0]).AddInput(a0, a1)
			})
		}
	} else if _, ok := accum.(addInput2x1[T0, T0]); ok {
		caller := func(fn any) reflectx.Func {
			f := fn.(func(T0, T0) T0)

View on GitHub (pinned to 12126d8942)

Solutions

  1. Change CreateAccumulator to return exactly the accumulator type: `func (c *MyCombiner) CreateAccumulator() T` or `func (c *MyCombiner) CreateAccumulator() (T, error)`.
  2. Ensure the type parameter passed to Combiner1[T0]/Combiner2[T0,T1] matches the actual accumulator return type (check Combiner2's [AccumT, OtherT] order).
  3. If accumulator type differs from input/output type, switch from Combiner1 to Combiner2[T0, T1] with T0 = accumulator type.
  4. Remove the CreateAccumulator method entirely if a zero value accumulator is acceptable (the wrapper is only mandatory for methods that exist).

Example fix

// before
func (c *IntSum) CreateAccumulator() (int64, error) { return 0, nil }
register.Combiner1[int](&IntSum{})

// after
func (c *IntSum) CreateAccumulator() (int, error) { return 0, nil }
register.Combiner1[int](&IntSum{})
Defensive patterns

Strategy: validation

Validate before calling

// Run at init time to fail fast:
var _ interface{ CreateAccumulator() int } = (*MyCombiner)(nil)
// Or both supported shapes:
// var _ interface{ CreateAccumulator() (int, error) } = (*MyCombiner)(nil)
func validateCreateAccumulator[T0 any](c any) bool {
	_, e1 := c.(interface{ CreateAccumulator() T0 })
	_, e2 := c.(interface{ CreateAccumulator() (T0, error) })
	return e1 || e2
}

Type guard

func hasTypedCreateAccumulator[T0 any](c any) bool {
	_, ok1 := c.(interface{ CreateAccumulator() T0 })
	_, ok2 := c.(interface{ CreateAccumulator() (T0, error) })
	return ok1 || ok2
}

Prevention

When it happens

Trigger: Calling register.Combiner1[T](&myCombiner{}) (or Combiner2) where myCombiner defines CreateAccumulator with a signature that is neither `CreateAccumulator() T` nor `CreateAccumulator() (T, error)` for the supplied type parameter T — e.g. it returns a different type than T0, takes arguments, or T was inferred/written incorrectly.

Common situations: Passing the wrong type parameter (Combiner2[AccumT, InputT] argument order swapped, or Combiner1[T] where the accumulator type differs from input type); a custom CombineFn whose CreateAccumulator returns a struct type different from the declared generic; upgrading Beam and migrating from reflection-based registration to the new typed Combiner registration API.

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


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