apache/beam · error

type var must be a universal type

Error message

type var %s must be a universal type

What it means

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.

Solutions

  1. Create the Var with typex.NewVariable(name) so IsUniversal passes.
  2. Swap the Var and T fields if they were accidentally reversed in the TypeDefinition literal.
  3. Remove the TypeDefinition if a concrete type was intended — encode it directly in the function signature instead.

Example fix

// before
beam.TypeDefinition{Var: typex.T, T: reflect.TypeOf("")}
// after
beam.TypeDefinition{Var: typex.NewVariable("T"), T: reflect.TypeOf("")}
Defensive patterns

Strategy: validation

Validate before calling

if !typex.IsUniversal(td.Var) {
    return fmt.Errorf("TypeDefinition.Var %v must be created with typex.NewVariable", td.Var)
}

Type guard

func validTypedef(td beam.TypeDefinition) bool {
    return typex.IsUniversal(td.Var)
}

Try / catch

if err := beam.TryParDo(s, fn, col, opts...); err != nil {
    return fmt.Errorf("ParDo rejected: %w", err)
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/79166935534820c7. Report an issue: GitHub.

Appendix: source

Thrown at sdks/go/pkg/beam/validate.go:72

	}
	side, defs := parseOpts(opts)
	for i, in := range side {
		if !in.Input.IsValid() {
			return nil, nil, errors.Errorf("invalid side pcollection: index %v", i)
		}
	}
	typedefs, err := makeTypedefs(defs)
	if err != nil {
		return nil, nil, err
	}
	return side, typedefs, nil
}

func makeTypedefs(list []TypeDefinition) (map[string]reflect.Type, error) {
	typedefs := make(map[string]reflect.Type)
	for _, v := range list {
		if !typex.IsUniversal(v.Var) {
			return nil, errors.Errorf("type var %s must be a universal type", v.Var)
		}
		if ok, err := typex.CheckConcrete(v.T); !ok {
			return nil, errors.Wrapf(err, "type value %s must be a concrete type", v.T)
		}
		typedefs[v.Var.Name()] = v.T
	}
	return typedefs, nil
}

View on GitHub (pinned to 12126d8942)