{"record":{"id":"79166935534820c7","repo":"apache/beam","slug":"type-var-s-must-be-a-universal-type","errorCode":null,"errorMessage":"type var %s must be a universal type","messagePattern":"type var (.+?) must be a universal type","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/validate.go","lineNumber":72,"sourceCode":"\t}\n\tside, defs := parseOpts(opts)\n\tfor i, in := range side {\n\t\tif !in.Input.IsValid() {\n\t\t\treturn nil, nil, errors.Errorf(\"invalid side pcollection: index %v\", i)\n\t\t}\n\t}\n\ttypedefs, err := makeTypedefs(defs)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\treturn side, typedefs, nil\n}\n\nfunc makeTypedefs(list []TypeDefinition) (map[string]reflect.Type, error) {\n\ttypedefs := make(map[string]reflect.Type)\n\tfor _, v := range list {\n\t\tif !typex.IsUniversal(v.Var) {\n\t\t\treturn nil, errors.Errorf(\"type var %s must be a universal type\", v.Var)\n\t\t}\n\t\tif ok, err := typex.CheckConcrete(v.T); !ok {\n\t\t\treturn nil, errors.Wrapf(err, \"type value %s must be a concrete type\", v.T)\n\t\t}\n\t\ttypedefs[v.Var.Name()] = v.T\n\t}\n\treturn typedefs, nil\n}\n","sourceCodeStart":54,"sourceCodeEnd":81,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/validate.go#L54-L81","documentation":"makeTypedefs registers user-supplied type variables for a DoFn. Each TypeDefinition.Var must be a universal type variable (typex.IsUniversal), i.e. a proper type parameter like typex.NewVariable; anything else cannot stand in for arbitrary types.","triggerScenarios":"Passing a TypeDefinition whose Var is a concrete type or non-universal typex.T instead of a type variable created with typex.NewVariable, when calling TryParDo/TryCombinePerKey with TypeDefinition options.","commonSituations":"Confusing Var and T fields in beam.TypeDefinition; copying an example but passing typex.T's concrete type where a variable is expected; older code written against a different typex API.","solutions":["Create the Var with typex.NewVariable(name) so IsUniversal passes.","Swap the Var and T fields if they were accidentally reversed in the TypeDefinition literal.","Remove the TypeDefinition if a concrete type was intended — encode it directly in the function signature instead."],"exampleFix":"// before\nbeam.TypeDefinition{Var: typex.T, T: reflect.TypeOf(\"\")}\n// after\nbeam.TypeDefinition{Var: typex.NewVariable(\"T\"), T: reflect.TypeOf(\"\")}","handlingStrategy":"validation","validationCode":"if !typex.IsUniversal(td.Var) {\n    return fmt.Errorf(\"TypeDefinition.Var %v must be created with typex.NewVariable\", td.Var)\n}","typeGuard":"func validTypedef(td beam.TypeDefinition) bool {\n    return typex.IsUniversal(td.Var)\n}","tryCatchPattern":"if err := beam.TryParDo(s, fn, col, opts...); err != nil {\n    return fmt.Errorf(\"ParDo rejected: %w\", err)\n}","preventionTips":["Always construct Var with typex.NewVariable(name).","Don't swap the Var and T fields in beam.TypeDefinition literals.","Review beam.TryParDo docs on TypeDefinition before writing custom type bindings."],"tags":["beam","types","validation"],"backgroundTag":"type-mismatch","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"}