{"record":{"id":"d8b560602eed4d22","repo":"apache/beam","slug":"failed-to-create-typekey-for-receiver-type-t","errorCode":null,"errorMessage":"failed to create TypeKey for receiver type %T","messagePattern":"failed to create TypeKey for receiver type %T","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/runtime/graphx/serialize.go","lineNumber":244,"sourceCode":"\t\t\tName: u.DynFn.Name,\n\t\t\tType: t,\n\t\t\tData: u.DynFn.Data,\n\t\t\tGen:  gen,\n\t\t}}, nil\n\n\tcase u.Fn != nil:\n\t\tfn, err := encodeUserFn(u.Fn)\n\t\tif err != nil {\n\t\t\twrapped := errors.Wrap(err, \"bad userfn\")\n\t\t\treturn nil, errors.WithContextf(wrapped, \"encoding DoFn %v\", u)\n\t\t}\n\t\treturn &v1pb.Fn{Fn: fn}, nil\n\n\tcase u.Recv != nil:\n\t\tt := reflect.TypeOf(u.Recv)\n\t\tk, ok := runtime.TypeKey(reflectx.SkipPtr(t))\n\t\tif !ok {\n\t\t\terr := errors.Errorf(\"failed to create TypeKey for receiver type %T\", u.Recv)\n\t\t\treturn nil, errors.WithContextf(err, \"encoding structural DoFn %v\", u)\n\t\t}\n\t\tif _, ok := runtime.LookupType(k); !ok {\n\t\t\terr := errors.Errorf(\"receiver type %v must be registered\", t)\n\t\t\treturn nil, errors.WithContextf(err, \"encoding structural DoFn %v\", u)\n\t\t}\n\t\ttyp, err := encodeType(t)\n\t\tif err != nil {\n\t\t\twrapped := errors.Wrapf(err, \"failed to encode receiver type %T\", u.Recv)\n\t\t\treturn nil, errors.WithContextf(wrapped, \"encoding structural DoFn %v\", u)\n\t\t}\n\n\t\tdata, err := jsonx.Marshal(u.Recv)\n\t\tif err != nil {\n\t\t\twrapped := errors.Wrapf(err, \"failed to marshal receiver %v\", u.Recv)\n\t\t\treturn nil, errors.WithContextf(wrapped, \"encoding structural DoFn %v\", u)\n\t\t}\n\t\treturn &v1pb.Fn{Type: typ, Opt: string(data)}, nil","sourceCodeStart":226,"sourceCodeEnd":262,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/runtime/graphx/serialize.go#L226-L262","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nvar fn **MyDoFn = &ptr\nbeam.ParDo(s, fn, in)\n// after\nd := &MyDoFn{}\nbeam.ParDo(s, d, in)","handlingStrategy":"type-guard","validationCode":"func isValidDoFnRecv(recv interface{}) error {\n\tt := reflect.TypeOf(recv)\n\tfor t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Ptr {\n\t\tt = t.Elem()\n\t}\n\tif _, ok := runtime.TypeKey(reflectx.SkipPtr(t)); !ok {\n\t\treturn fmt.Errorf(\"receiver type %v cannot be keyed; pass &Struct{} instead\", t)\n\t}\n\treturn nil\n}","typeGuard":"func isPlainStructOrPtr(recv interface{}) bool {\n\tt := reflectx.SkipPtr(reflect.TypeOf(recv))\n\treturn t.Kind() == reflect.Struct\n}","tryCatchPattern":"me, err := graphx.EncodeMultiEdge(edge)\nif err != nil && strings.Contains(err.Error(), \"failed to create TypeKey\") {\n\treturn fmt.Errorf(\"DoFn receiver type unsupported: pass a struct pointer: %w\", err)\n}","preventionTips":["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"],"tags":["go","beam","dofn","type-key"],"backgroundTag":"invalid-argument-value","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"}