apache/beam · error

failed to create TypeKey for receiver type %T

Error message

failed to create TypeKey for receiver type %T

What it means

encodeFn handles structural (receiver-based) DoFns (u.Recv). It derives a TypeKey from the receiver type via reflectx.SkipPtr; if a TypeKey cannot be constructed (e.g. unsupported kinds like interfaces, unexported/odd composite types), the error "failed to create TypeKey for receiver type %T" is raised. Beam must be able to key the receiver type to serialize it.

Solutions

  1. Pass the DoFn as a plain struct value or single pointer (&MyDoFn{})
  2. Remove extra pointer/interface wrapping around the DoFn before passing to beam.ParDo
  3. Ensure the concrete receiver type is a struct with representable kinds
  4. If intentional, register the type so a stable key exists

Example fix

// before
var fn **MyDoFn = &ptr
beam.ParDo(s, fn, in)
// after
d := &MyDoFn{}
beam.ParDo(s, d, in)
Defensive patterns

Strategy: type-guard

Validate before calling

func isValidDoFnRecv(recv interface{}) error {
	t := reflect.TypeOf(recv)
	for t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Ptr {
		t = t.Elem()
	}
	if _, ok := runtime.TypeKey(reflectx.SkipPtr(t)); !ok {
		return fmt.Errorf("receiver type %v cannot be keyed; pass &Struct{} instead", t)
	}
	return nil
}

Type guard

func isPlainStructOrPtr(recv interface{}) bool {
	t := reflectx.SkipPtr(reflect.TypeOf(recv))
	return t.Kind() == reflect.Struct
}

Try / catch

me, err := graphx.EncodeMultiEdge(edge)
if err != nil && strings.Contains(err.Error(), "failed to create TypeKey") {
	return fmt.Errorf("DoFn receiver type unsupported: pass a struct pointer: %w", err)
}

Prevention

When it happens

Trigger: encodeFn receives an Fn whose Recv is a pointer-to-pointer or type whose skipped form has no valid TypeKey (e.g. interface, chan, func kinds), during EncodeMultiEdge.

Common situations: Passing a **T or interface-typed receiver as a DoFn; passing values of kinds TypeKey cannot represent; nested pointer wrappers around the intended DoFn struct.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at sdks/go/pkg/beam/core/runtime/graphx/serialize.go:244

			Name: u.DynFn.Name,
			Type: t,
			Data: u.DynFn.Data,
			Gen:  gen,
		}}, nil

	case u.Fn != nil:
		fn, err := encodeUserFn(u.Fn)
		if err != nil {
			wrapped := errors.Wrap(err, "bad userfn")
			return nil, errors.WithContextf(wrapped, "encoding DoFn %v", u)
		}
		return &v1pb.Fn{Fn: fn}, nil

	case u.Recv != nil:
		t := reflect.TypeOf(u.Recv)
		k, ok := runtime.TypeKey(reflectx.SkipPtr(t))
		if !ok {
			err := errors.Errorf("failed to create TypeKey for receiver type %T", u.Recv)
			return nil, errors.WithContextf(err, "encoding structural DoFn %v", u)
		}
		if _, ok := runtime.LookupType(k); !ok {
			err := errors.Errorf("receiver type %v must be registered", t)
			return nil, errors.WithContextf(err, "encoding structural DoFn %v", u)
		}
		typ, err := encodeType(t)
		if err != nil {
			wrapped := errors.Wrapf(err, "failed to encode receiver type %T", u.Recv)
			return nil, errors.WithContextf(wrapped, "encoding structural DoFn %v", u)
		}

		data, err := jsonx.Marshal(u.Recv)
		if err != nil {
			wrapped := errors.Wrapf(err, "failed to marshal receiver %v", u.Recv)
			return nil, errors.WithContextf(wrapped, "encoding structural DoFn %v", u)
		}
		return &v1pb.Fn{Type: typ, Opt: string(data)}, nil

View on GitHub (pinned to 12126d8942)