{"record":{"id":"f7978b41715d1f00","repo":"micro/go-micro","slug":"v-argument-type-not-exported-v","errorCode":null,"errorMessage":"%v argument type not exported: %v","messagePattern":"(.+?) argument type not exported: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/grpc/subscriber.go","lineNumber":153,"sourceCode":"\t\t\treturn fmt.Errorf(\"subscriber %v returns %v not error\", name, returnType.String())\n\t\t}\n\t} else {\n\t\thdlr := reflect.ValueOf(sub.Subscriber())\n\t\tname := reflect.Indirect(hdlr).Type().Name()\n\n\t\tfor m := 0; m < typ.NumMethod(); m++ {\n\t\t\tmethod := typ.Method(m)\n\n\t\t\tswitch method.Type.NumIn() {\n\t\t\tcase 3:\n\t\t\t\targType = method.Type.In(2)\n\t\t\tdefault:\n\t\t\t\treturn fmt.Errorf(\"subscriber %v.%v takes wrong number of args: %v required signature %s\",\n\t\t\t\t\tname, method.Name, method.Type.NumIn(), subSig)\n\t\t\t}\n\n\t\t\tif !isExportedOrBuiltinType(argType) {\n\t\t\t\treturn fmt.Errorf(\"%v argument type not exported: %v\", name, argType)\n\t\t\t}\n\t\t\tif method.Type.NumOut() != 1 {\n\t\t\t\treturn fmt.Errorf(\n\t\t\t\t\t\"subscriber %v.%v has wrong number of outs: %v require signature %s\",\n\t\t\t\t\tname, method.Name, method.Type.NumOut(), subSig)\n\t\t\t}\n\t\t\tif returnType := method.Type.Out(0); returnType != typeOfError {\n\t\t\t\treturn fmt.Errorf(\"subscriber %v.%v returns %v not error\", name, method.Name, returnType.String())\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (g *grpcServer) createSubHandler(sb *subscriber, opts server.Options) broker.Handler {\n\treturn func(p broker.Event) (err error) {\n\t\tdefer func() {","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/server/grpc/subscriber.go#L135-L171","documentation":"During subscriber registration, go-micro's gRPC server validates that every handler method's single argument type is either a builtin or an exported type. If the message type passed to the subscriber method is unexported (e.g. starts with a lowercase letter) the server cannot reliably encode/decode or introspect it, so Subscribe fails with this error instead of registering the subscriber.","triggerScenarios":"Calling server.Subscribe() with a Subscriber whose handler method signature is like `func (s *Handler) handleMsg(msgType)` where `msgType` is an unexported (lowercase) struct type defined in the handler's package.","commonSituations":"Developers define message structs in a private package or accidentally lowercase the message type name; generated protobuf types are exported but hand-written internal event types often are not.","solutions":["Rename the handler's argument struct to start with an uppercase letter so it is exported","Move the message type to a shared package and export it","If the argument is a Go builtin (string, []byte, map, etc.) no change is needed — check that you are not wrapping it in an unexported alias"],"exampleFix":"// before\ntype handler struct{}\nfunc (h *handler) Handle(evt event) error { ... } // 'event' unexported\n// after\ntype Event struct{ ... }\nfunc (h *handler) Handle(evt *Event) error { ... }","handlingStrategy":"validation","validationCode":"func validSubscriberArg(fn interface{}) bool {\n\tt := reflect.TypeOf(fn)\n\tif t.NumIn() != 3 { return false } // receiver, ctx, msg\n\targ := t.In(2)\n\tif arg.Kind() == reflect.Ptr { arg = arg.Elem() }\n\treturn arg.PkgPath() == \"\" || arg.Name()[0] >= 'A' && arg.Name()[0] <= 'Z' // builtin or exported\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always declare subscriber message types as exported structs, typically protobuf-generated types","Keep the handler signature exactly func(ctx context.Context, msg *T) error","Write a unit test that calls Subscribe for every subscriber at startup (fail fast on boot)"],"tags":["grpc","subscriber","reflection","go"],"backgroundTag":"subscriber-signature-mismatch","analyzedSha":"24529f140421a11a33b6999ab7944f2021cfd69c","analyzedAt":"2026-09-01T02:52:24.923Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}