{"record":{"id":"27a489185fc05953","repo":"micro/go-micro","slug":"invalid-subscriber-expected-subscriber-27a489","errorCode":null,"errorMessage":"invalid subscriber: expected *subscriber","messagePattern":"invalid subscriber: expected \\*subscriber","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/rpc_events.go","lineNumber":89,"sourceCode":"\t\t\t\treturn handler(ctx, msg)\n\t\t\t}}\n\t\t}\n\n\t\treturn r.ProcessMessage(ctx, subscriber, rpcMsg)\n\t}\n}\n\nfunc (s *rpcServer) NewSubscriber(topic string, sb interface{}, opts ...SubscriberOption) Subscriber {\n\treturn s.router.NewSubscriber(topic, sb, opts...)\n}\n\nfunc (s *rpcServer) Subscribe(sb Subscriber) error {\n\ts.Lock()\n\tdefer s.Unlock()\n\n\tsub, ok := sb.(*subscriber)\n\tif !ok {\n\t\treturn fmt.Errorf(\"invalid subscriber: expected *subscriber\")\n\t}\n\tif len(sub.handlers) == 0 {\n\t\treturn fmt.Errorf(\"invalid subscriber: no handler functions\")\n\t}\n\n\tif err := validateSubscriber(sub); err != nil {\n\t\treturn err\n\t}\n\n\t// append to subscribers\n\t// subs := s.subscribers[sub.Topic()]\n\t// subs = append(subs, sub)\n\t// router.subscribers[sub.Topic()] = subs\n\n\ts.subscribers[sb] = nil\n\n\treturn nil\n}","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/server/rpc_events.go#L71-L107","documentation":"rpcServer.Subscribe accepts only the library-internal `*subscriber` implementation of the Subscriber interface. Passing any other value — a custom type that implements the interface or a nil value — is rejected with this error because the server needs internal fields (topic, handlers) it can only access on the concrete type.","triggerScenarios":"Calling `server.Subscribe(x)` where x is nil, a Subscriber from a different go-micro/server implementation, or a hand-rolled type implementing the Subscriber interface instead of one created by `server.NewSubscriber`.","commonSituations":"Mixing servers/subscribers from different micro frameworks or versions; passing a nil variable; writing a mock or custom Subscriber for tests and passing it to the real server.","solutions":["Create subscribers with `server.NewSubscriber(topic, handler, opts...)` from the same package/version as the server and pass that to Subscribe","Check that the value is non-nil before calling Subscribe","Use the same go-micro server package throughout (do not mix grpc and default server subscriber types)"],"exampleFix":"// before\nvar sb server.Subscriber\nserver.Subscribe(sb) // nil / foreign type\n// after\nsb, err := server.NewSubscriber(\"topic\", handler, server.SubscriberQueue(\"q\"))\nif err != nil { return err }\nreturn server.Subscribe(sb)","handlingStrategy":"type-guard","validationCode":"if sb == nil {\n\treturn errors.New(\"subscriber must be created via server.NewSubscriber\")\n}","typeGuard":"func isInternalSubscriber(sb server.Subscriber) bool {\n\t_, ok := sb.(*server.Subscriber) // concrete internal type used by the running server\n\treturn ok\n}","tryCatchPattern":"if err := server.Subscribe(sb); err != nil {\n\tif strings.Contains(err.Error(), \"invalid subscriber: expected *subscriber\") {\n\t\t// rebuild via server.NewSubscriber before retrying\n\t}\n}","preventionTips":["Always construct subscribers with server.NewSubscriber, never implement the Subscriber interface by hand","Guard against passing nil subscriber variables before calling Subscribe","Keep all go-micro packages on one version so interface implementations match"],"tags":["grpc","subscriber","type-assertion","go"],"backgroundTag":"invalid-subscriber-type","analyzedSha":"24529f140421a11a33b6999ab7944f2021cfd69c","analyzedAt":"2026-09-01T02:52:24.923Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}