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

  1. Add a required parameter or return of the generic type so it gets bound during generic binding.
  2. Replace the generic in the optional position with a concrete type.
  3. 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

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


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