apache/beam · error
typex.Bind: invalid number of models
Error message
typex.Bind: invalid number of models: %v, want %v
What it means
typex.Bind substitutes concrete types for universals in a FullType signature: each provided model must correspond one-to-one with the types being bound. This error is returned when len(models) != len(types), so the substitution cannot proceed — the caller supplied a mismatched number of model types. Exposed publicly, so users invoking Bind directly (or via TestBindSubstitute) hit it.
Solutions
- Ensure models has exactly one FullType per element of types, in order, before calling Bind.
- If binding composite types (KV, CoGBK), expand the signature into its component FullTypes and provide one model per component.
- Guard the call: check len(types) == len(models) or pass through the signature's full type list programmatically.
- Prefer deriving models from the DoFn signature (typex.FullSignature) rather than hard-coding lists so arity stays in sync.
Example fix
// before
subst, err := typex.Bind([]typex.FullType{tKV}, []typex.FullType{model}) // arity mismatch
// after
kv := tKV.(typex.KVFullType)
subst, err := typex.Bind(kv.Components(), []typex.FullType{kvModel, intModel}) Defensive patterns
Strategy: validation
Validate before calling
if len(models) != len(types) {
return fmt.Errorf("typex.Bind needs %d models, got %d", len(types), len(models))
} Type guard
func canBind(types, models []typex.FullType) bool {
return len(types) == len(models)
} Try / catch
subst, err := typex.Bind(types, models)
if err != nil {
return nil, fmt.Errorf("bind failed (types=%d models=%d): %w", len(types), len(models), err)
} Prevention
- Derive models from typex.FullSignature components instead of hard-coded lists.
- For composite types, bind per-component FullTypes with matching arity.
- Assert arity equality in tests around type substitution.
When it happens
Trigger: Calling typex.Bind with a different number of FullTypes than models — e.g. binding a single-type signature with two models, or passing a KV signature's components but forgetting one model; callers misusing Bind recursively (Bind calls itself on component types).
Common situations: Custom DoFn/framework code performing manual type substitution on multi-type signatures (KV, CoGBK); tests substituting universals with incomplete model lists; refactors that change arity of a signature without updating Bind call sites.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Nested type in map " " not permitted in concrete types.
- Nested type in struct
- Nested type in " " not permitted in concrete types.
- Special type " " not permitted in concrete types
- Type " " of kind " " not permitted in concrete types. All…
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/f72b3355221b2def.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/go/pkg/beam/core/typex/fulltype.go:351
func IsBound(t FullType) bool {
if t.Class() == Universal {
return false
}
for _, elm := range t.Components() {
if !IsBound(elm) {
return false
}
}
return true
}
// Bind returns a substitution from universals to types in the given models,
// such as {"T" -> X, "X" -> int}. Each model must be assignable to the
// corresponding type. For example, Bind(KV<T,int>, KV<string, int>) would
// produce {"T" -> string}.
func Bind(types, models []FullType) (map[string]reflect.Type, error) {
if len(types) != len(models) {
return nil, errors.Errorf("typex.Bind: invalid number of models: %v, want %v", len(models), len(types))
}
m := make(map[string]reflect.Type)
for i := 0; i < len(types); i++ {
t := types[i]
model := models[i]
if !IsStructurallyAssignable(model, t) {
return nil, errors.Errorf("typex.Bind: %v is not assignable to %v", model, t)
}
if err := walk(t, model, m); err != nil {
return nil, err
}
}
return m, nil
}
func walk(t, model FullType, m map[string]reflect.Type) error {View on GitHub (pinned to 12126d8942)