{"record":{"id":"22778e38e5354752","repo":"apache/beam","slug":"typex-bind-v-is-not-assignable-to-v","errorCode":null,"errorMessage":"typex.Bind: %v is not assignable to %v","messagePattern":"typex\\.Bind: (.+?) is not assignable to (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/typex/fulltype.go","lineNumber":360,"sourceCode":"\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 {\n\tswitch t.Class() {\n\tcase Universal:\n\t\t// By checking that the model is assignable to t, we know that they are\n\t\t// structurally compatible. We rely on the exact reflect.Type in the\n\t\t// Aggregate case to pick the correct binding, i.e., we do not need to\n\t\t// construct such a type.\n\n\t\tname := t.Type().Name()\n\t\tif current, ok := m[name]; ok && current != model.Type() {","sourceCodeStart":342,"sourceCodeEnd":378,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/typex/fulltype.go#L342-L378","documentation":"typex.Bind creates a binding from type variables (models) to concrete Go types. Each actual type must be structurally assignable to its corresponding model; if IsStructurallyAssignable fails, Bind refuses to build the map and returns this error naming the model and the offending type.","triggerScenarios":"Calling typex.Bind(models, types) where the i-th concrete type does not structurally match the i-th model — e.g. binding an int against a variable typed as X<int>, mismatched container element types, or supplying fewer/mismatched pairs so models[i] cannot accept types[i].","commonSituations":"Users defining a DoFn or CombineFn with generic type variables pass user data whose shape doesn't match the declared variable structure; common after refactoring a pipeline's PCollection element type (e.g. T to string) without updating the typex.NewVariable/T types passed to Bind.","solutions":["Check the two %v values in the message: the first is the model (type variable) and the second your concrete type; align the concrete type's structure with the model.","Verify argument order — Bind expects (models, types); swapping them produces spurious assignment failures.","Use typex.New / typex.T, typex.X etc. to construct models matching the exact container/composite shape of your runtime type.","Print reflect.TypeOf on the value and compare element kinds (slice vs array, key/value types) with the model before calling Bind."],"exampleFix":"// before\ntypex.Bind([]typex.FullType{typex.New(typex.X(typex.T))}, []typex.FullType{typex.New(reflect.TypeOf(42))}) // X<int> model vs int\n\n// after\ntypex.Bind([]typex.FullType{typex.New(typex.T)}, []typex.FullType{typex.New(reflect.TypeOf(42))})","handlingStrategy":"validation","validationCode":"func canBind(models, types []typex.FullType) bool {\n    if len(models) != len(types) {\n        return false\n    }\n    for i := range models {\n        if !typex.IsStructurallyAssignable(models[i], types[i]) {\n            return false\n        }\n    }\n    return true\n}","typeGuard":"if mt, ok := value.(typex.FullType); ok && typex.IsStructurallyAssignable(model, mt) { /* safe to Bind */ }","tryCatchPattern":"m, err := typex.Bind(models, types)\nif err != nil {\n    return fmt.Errorf(\"type binding failed: %w\", err)\n}","preventionTips":["Construct models with typex.T/typex.X helpers that mirror the exact container shape of your runtime types.","Always pass concrete reflect-derived types (typex.New(reflect.TypeOf(v))) rather than guessed FullTypes.","Check len(models) == len(types) before calling Bind.","Add a unit test that Binds your Fn's signature against the actual PCollection element types."],"tags":["go","apache-beam","type-binding","generics"],"backgroundTag":"type-mismatch","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}