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
- Pass the DoFn as a plain struct value or single pointer (&MyDoFn{})
- Remove extra pointer/interface wrapping around the DoFn before passing to beam.ParDo
- Ensure the concrete receiver type is a struct with representable kinds
- 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
- Pass DoFns as struct values or single pointers, never **T or interfaces
- Avoid chan/func/interface-kinded receiver types
- Register structural DoFn types via beam.RegisterType
- Guard helper wrappers so they don't add extra pointer indirection
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
- bad function type
- bad parameter type for
- cannot substitute type
- DoFns that observe windows must be invoked with single…
- Duplicate timer family ID
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)}, nilView on GitHub (pinned to 12126d8942)