apache/beam · error
Invalid signature for FinishBundle
Error message
Invalid signature for FinishBundle
What it means
This panic is the inner default of buildFinishBundleWrapper for the 0-input case: the FinishBundle output count was neither 0 nor 1. Beam only permits FinishBundle to return nothing or a single error, so any other number of return values is an invalid signature and registration aborts.
Source
Thrown at sdks/go/pkg/beam/register/register.go:1275
finishBundleOut = finishBundleMethod.Type().NumOut()
switch {
case finishBundleIn == 0:
switch {
case finishBundleOut == 0:
if _, ok := doFn.(finishBundle0x0); ok {
return registerFinishBundle0x0FuncAndMakeStructWrapper()
} else {
panic("Unable to infer the types of FinishBundle")
}
case finishBundleOut == 1:
if _, ok := doFn.(finishBundle0x1[error]); ok {
return registerFinishBundle0x1FuncAndMakeStructWrapper[error]()
} else {
panic("Unable to infer the types of FinishBundle")
}
default:
panic("Invalid signature for FinishBundle")
}
case finishBundleIn == 1:
switch {
case finishBundleOut == 0:
if _, ok := doFn.(finishBundle1x0[I9]); ok {
return registerFinishBundle1x0FuncAndMakeStructWrapper[I9]()
} else if _, ok := doFn.(finishBundle1x0[context.Context]); ok {
return registerFinishBundle1x0FuncAndMakeStructWrapper[context.Context]()
} else if _, ok := doFn.(finishBundle1x0[typex.PaneInfo]); ok {
return registerFinishBundle1x0FuncAndMakeStructWrapper[typex.PaneInfo]()
} else if _, ok := doFn.(finishBundle1x0[[]typex.Window]); ok {
return registerFinishBundle1x0FuncAndMakeStructWrapper[[]typex.Window]()
} else if _, ok := doFn.(finishBundle1x0[typex.EventTime]); ok {
return registerFinishBundle1x0FuncAndMakeStructWrapper[typex.EventTime]()
} else if _, ok := doFn.(finishBundle1x0[typex.BundleFinalization]); ok {
return registerFinishBundle1x0FuncAndMakeStructWrapper[typex.BundleFinalization]()
} else {View on GitHub (pinned to 12126d8942)
Solutions
- Change FinishBundle to return nothing or exactly one error value.
- Log diagnostics instead of returning extra values from FinishBundle.
- Move metrics/extra outputs to ProcessElement or bundle finalization callbacks (BundleFinalization).
- Re-run registration after fixing; the panic occurs at pipeline construction time, not runtime execution.
Example fix
// before
func (fn *myFn) FinishBundle() (int, error) { ... }
// after
func (fn *myFn) FinishBundle() error { ... } Defensive patterns
Strategy: validation
Validate before calling
t := reflect.TypeOf(&myFn{}).Elem().MethodByName("FinishBundle").Type
if t.NumOut() > 1 { panic("FinishBundle may return at most one error") }
Type guard
func atMostOneReturn(t reflect.Type) bool { return t.NumOut() <= 1 }
Try / catch
defer func() { if r := recover(); r != nil { err = fmt.Errorf("FinishBundle arity invalid: %v", r) } }()
Prevention
- FinishBundle returns zero values or a single error
- Log instead of returning diagnostics
- Review signatures when copying from other DoFn methods
When it happens
Trigger: A FinishBundle method with no inputs returning two or more values (e.g. (int, error)) or three values, then the DoFn is registered via register.DoFn/used in a pipeline.
Common situations: Copying ProcessElement's multi-return style onto FinishBundle; adding a debug return value to FinishBundle during development and forgetting to remove it.
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
- bad parameter type for %s: %v
- GBK/CoGBK result values must be iterable: %v
- Invalid signature for StartBundle
- Unable to infer the types of FinishBundle
- first main input parameter must be a value type
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/8262a8f16b1805a3.
Report an issue: GitHub.