{"record":{"id":"16c57c940fa3bfd0","repo":"apache/beam","slug":"bind-conflict-for-v-v-v-fulltype","errorCode":null,"errorMessage":"bind conflict for %v: %v != %v","messagePattern":"bind conflict for (.+?): (.+?) != (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/typex/fulltype.go","lineNumber":379,"sourceCode":"\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() {\n\t\t\treturn errors.Errorf(\"bind conflict for %v: %v != %v\", name, current, model.Type())\n\t\t}\n\t\tm[name] = model.Type()\n\t\treturn nil\n\tcase Composite, Container:\n\t\tfor i, elm := range t.Components() {\n\t\t\tif err := walk(elm, model.Components()[i], m); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\treturn nil\n\tdefault:\n\t\treturn nil\n\t}\n}\n\n// Substitute returns types identical to the given types, but with all\n// universals substituted. All free type variables must be present in the\n// substitution.","sourceCodeStart":361,"sourceCodeEnd":397,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/typex/fulltype.go#L361-L397","documentation":"While walking a type tree during typex.Bind, the same type-variable name maps to two different concrete reflect.Types. The walk detects the conflict and aborts, since one variable name cannot bind to inconsistent concrete types.","triggerScenarios":"A single type variable (e.g. T) appears in multiple positions of the model, and Bind is given concrete types that resolve T to different reflect.Types — e.g. X<T> paired with []string and X<int> paired with []int in the same Bind call.","commonSituations":"Users write a generic DoFn with a repeated type variable but feed heterogeneous input (e.g. KV<A,B> where they reused T for both A and B); also occurs when a custom aggregation or coders inference passes mismatched inputs to a multi-input step.","solutions":["Unify the concrete types so the repeated variable binds to exactly one reflect.Type, or use distinct variables (T, U) in the model.","Inspect the message: name is the variable, then the two conflicting concrete types; change whichever one is wrong in your Fn signature.","If the inputs are genuinely different types, change your PTransform signature to use separate type parameters instead of reusing one.","Call typex.Bind with the pair whose conflict the message flags to reproduce and confirm before editing larger code."],"exampleFix":"// before — one variable bound to two types\nfunc (fn *dedupFn) ProcessElement(a T, b T)\n// pipeline gives a=string, b=int\n\n// after — distinct variables\nfunc (fn *dedupFn) ProcessElement(a T, b U)","handlingStrategy":"validation","validationCode":"func bindsConsistently(models, types []typex.FullType) bool {\n    m, err := typex.Bind(models, types)\n    if err != nil {\n        return false\n    }\n    for _, v := range m { _ = v }\n    return true\n}","typeGuard":"// Ensure each variable name appears with one concrete type before Bind:\nseen := map[string]reflect.Type{}\nfor name, rt := range candidateBindings {\n    if prev, ok := seen[name]; ok && prev != rt {\n        return false // would cause bind conflict\n    }\n    seen[name] = rt\n}","tryCatchPattern":"m, err := typex.Bind(models, types)\nvar conflict *errors.E\nif err != nil && strings.Contains(err.Error(), \"bind conflict\") {\n    return fmt.Errorf(\"variable bound to two types; split into distinct type variables: %w\", err)\n}","preventionTips":["Never reuse the same type variable (typex.T) for two positions that can hold different concrete types.","Use distinct variables T, U, V for each independent input/output type in a DoFn or CombineFn.","Validate that multi-input transforms receive homogeneous types when a single variable covers them.","Keep Fn signatures and pipeline wiring in sync via code review or generated type checks."],"tags":["go","apache-beam","type-binding","conflict"],"backgroundTag":"conflicting-config-options","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"}