apache/beam · critical

Unable to infer the types of StartBundle

Error message

Unable to infer the types of StartBundle

What it means

buildStartBundleWrapper determines the concrete StartBundle method shape of a DoFn at registration time. When no StartBundle parameters could be inferred (startBundleIn == 0) and the DoFn does not implement the expected startBundle0x0 interface shape, it panics "Unable to infer the types of StartBundle". This happens when a user-defined StartBundle method has a signature the registration reflection code cannot map to a known wrapper.

Source

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

func buildStartBundleWrapper[I0, I1, I2, I3, I4, I5, I6, I7, I8, I9 any](doFn any) func(any) reflectx.Func {
	startBundleIn := -1
	startBundleOut := -1
	startBundleMethod := reflect.ValueOf(doFn).MethodByName("StartBundle")
	if !startBundleMethod.IsValid() {
		return nil
	}
	startBundleIn = startBundleMethod.Type().NumIn()
	startBundleOut = startBundleMethod.Type().NumOut()
	switch {

	case startBundleIn == 0:
		switch {
		case startBundleOut == 0:
			if _, ok := doFn.(startBundle0x0); ok {
				return registerStartBundle0x0FuncAndMakeStructWrapper()
			} else {
				panic("Unable to infer the types of StartBundle")
			}
		case startBundleOut == 1:
			if _, ok := doFn.(startBundle0x1[error]); ok {
				return registerStartBundle0x1FuncAndMakeStructWrapper[error]()
			} else {
				panic("Unable to infer the types of StartBundle")
			}
		default:
			panic("Invalid signature for StartBundle")
		}

	case startBundleIn == 1:
		switch {
		case startBundleOut == 0:
			if _, ok := doFn.(startBundle1x0[I9]); ok {
				return registerStartBundle1x0FuncAndMakeStructWrapper[I9]()
			} else if _, ok := doFn.(startBundle1x0[context.Context]); ok {
				return registerStartBundle1x0FuncAndMakeStructWrapper[context.Context]()

View on GitHub (pinned to 12126d8942)

Solutions

  1. Change StartBundle to a supported signature, e.g. func(*MyFn) StartBundle() error or with a beam context type.
  2. Return error from StartBundle if side effects can fail (startBundle0x1[error] shape).
  3. Verify receiver matches how the DoFn is registered (pointer vs value) so the type assertion succeeds.
  4. Check the beam SDK version's register.go for the exact list of supported StartBundle shapes.

Example fix

// before
func (f *MyFn) StartBundle(ctx context.Context) { ... } // not inferable

// after
func (f *MyFn) StartBundle() error {
    // bundle setup
    return nil
}
Defensive patterns

Strategy: validation

Validate before calling

// compile-time check the DoFn satisfies a supported shape
var _ interface{ StartBundle() error } = (*MyFn)(nil)

Type guard

func hasSupportedStartBundle(fn any) bool {
    _, ok0 := fn.(interface{ StartBundle() })
    _, ok1 := fn.(interface{ StartBundle() error })
    return ok0 || ok1
}

Prevention

When it happens

Trigger: Registering/using a DoFn whose StartBundle method matches none of the supported signatures: wrong parameter or return types (e.g. StartBundle(ctx) or StartBundle() with an unsupported return), or a generic instantiation that fails the startBundle0x0/startBundle0x1[error] type assertions.

Common situations: Typo'd or custom StartBundle signatures (extra params, missing context, wrong receiver generics); migrating DoFns across Beam versions where supported signatures changed; defining StartBundle on a value receiver vs pointer receiver mismatch so the type assertion fails.

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/09b30b0f049cb8e3. Report an issue: GitHub.