apache/beam · error
optional generic parameter not bound %v
Error message
optional generic parameter not bound %v
What it means
matchOpt in signature.go matches a function's optional parameters against the signature's optional model list. If an optional parameter is a universal (generic) type that was never bound in the substitution map (because no required parameter pinned it to a concrete type), the optional generic cannot be substituted and this error is returned.
Source
Thrown at sdks/go/pkg/beam/core/funcx/signature.go:214
}
// TypeMismatchError indicates we didn't get the type we expected.
type TypeMismatchError struct {
Got, Want reflect.Type
}
func (e *TypeMismatchError) Error() string {
return fmt.Sprintf("type mismatch: got %v, want %v", e.Got, e.Want)
}
func matchOpt(list, models []reflect.Type, m map[string]reflect.Type) error {
i := 0
for _, t := range list {
if typex.IsUniversal(t) {
// Substitute optional types, if bound.
subst, ok := m[t.Name()]
if !ok {
return errors.Errorf("optional generic parameter not bound %v", t.Name())
}
t = subst
}
for i < len(models) && models[i] != t {
i++
}
if i == len(models) {
return errors.Errorf("failed to match optional parameter %v", t)
}
}
return nil
}
// MustSatisfy panics if the given fn does not satisfy the signature.
func MustSatisfy(fn any, sig *Signature) {
if err := Satisfy(fn, sig); err != nil {
panic(errors.Wrapf(err, "fn does not satisfy signature %v", sig))View on GitHub (pinned to 12126d8942)
Solutions
- Add a required parameter or return of the generic type so it gets bound during generic binding.
- Replace the generic in the optional position with a concrete type.
- Reorder the function's parameters so the generic-typed one is required rather than optional.
Example fix
// before
sig := funcx.NewSignature(funcx.Args(typex.NewVariable("X")), funcx.OptArgs(typex.Fn(func(typex.T) bool))) // X never bound
// after
sig := funcx.NewSignature(funcx.Args(typex.NewVariable("X")), funcx.OptArgs(typex.Fn(func(typex.Event) bool))) // concrete optional Defensive patterns
Strategy: validation
Validate before calling
for _, opt := range sig.OptArgs {
if n := typex.UniversalName(opt); n != "" {
if _, bound := subst[n]; !bound {
return fmt.Errorf("generic %s used only in optional positions; add a required binding", n)
}
}
} Prevention
- Always bind generics through at least one required parameter or return.
- Avoid using universal types exclusively in optional/emitter positions.
- Prefer concrete types in optional parameters of custom signatures.
When it happens
Trigger: Calling Satisfy where a function's optional argument/return is a generic type (e.g. X) but no required parameter or return of the signature binds X to a concrete type, so map lookup m[X] fails.
Common situations: Signatures where only the optional (emitter/iter) positions use a generic; writing a DoFn with an optional emit func(X) but no required input of type X; misuse of typex.NewVariable/Universal types in custom signatures.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- bind conflict for %v: %v != %v
- cannot substitute type %v with %v, already defined as %v
- %v cannot bind to %v
- typex.Bind: %v is not assignable to %v
- Type interface{} isn't a supported PCollection type
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/29bb53c119f42fd6.
Report an issue: GitHub.