{"record":{"id":"f72b3355221b2def","repo":"apache/beam","slug":"typex-bind-invalid-number-of-models-v-want-v","errorCode":null,"errorMessage":"typex.Bind: invalid number of models: %v, want %v","messagePattern":"typex\\.Bind: invalid number of models: (.+?), want (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/typex/fulltype.go","lineNumber":351,"sourceCode":"func IsBound(t FullType) bool {\n\tif t.Class() == Universal {\n\t\treturn false\n\t}\n\tfor _, elm := range t.Components() {\n\t\tif !IsBound(elm) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// Bind returns a substitution from universals to types in the given models,\n// such as {\"T\" -> X, \"X\" -> int}. Each model must be assignable to the\n// corresponding type. For example, Bind(KV<T,int>, KV<string, int>) would\n// produce {\"T\" -> string}.\nfunc Bind(types, models []FullType) (map[string]reflect.Type, error) {\n\tif len(types) != len(models) {\n\t\treturn nil, errors.Errorf(\"typex.Bind: invalid number of models: %v, want %v\", len(models), len(types))\n\t}\n\n\tm := make(map[string]reflect.Type)\n\tfor i := 0; i < len(types); i++ {\n\t\tt := types[i]\n\t\tmodel := models[i]\n\n\t\tif !IsStructurallyAssignable(model, t) {\n\t\t\treturn nil, errors.Errorf(\"typex.Bind: %v is not assignable to %v\", model, t)\n\t\t}\n\t\tif err := walk(t, model, m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn m, nil\n}\n\nfunc walk(t, model FullType, m map[string]reflect.Type) error {","sourceCodeStart":333,"sourceCodeEnd":369,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/typex/fulltype.go#L333-L369","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nsubst, err := typex.Bind([]typex.FullType{tKV}, []typex.FullType{model}) // arity mismatch\n\n// after\nkv := tKV.(typex.KVFullType)\nsubst, err := typex.Bind(kv.Components(), []typex.FullType{kvModel, intModel})","handlingStrategy":"validation","validationCode":"if len(models) != len(types) {\n    return fmt.Errorf(\"typex.Bind needs %d models, got %d\", len(types), len(models))\n}","typeGuard":"func canBind(types, models []typex.FullType) bool {\n    return len(types) == len(models)\n}","tryCatchPattern":"subst, err := typex.Bind(types, models)\nif err != nil {\n    return nil, fmt.Errorf(\"bind failed (types=%d models=%d): %w\", len(types), len(models), err)\n}","preventionTips":["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."],"tags":["go","apache-beam","type-system","argument-count"],"backgroundTag":"invalid-argument-value","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}