{"record":{"id":"5ae4468b65cc5916","repo":"micro/go-micro","slug":"subscriber-v-takes-wrong-number-of-args-v-requi","errorCode":null,"errorMessage":"subscriber %v takes wrong number of args: %v required signature %s","messagePattern":"subscriber (.+?) takes wrong number of args: (.+?) required signature (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/grpc/subscriber.go","lineNumber":125,"sourceCode":"\t\ttopic:      topic,\n\t\tsubscriber: sub,\n\t\thandlers:   handlers,\n\t\tendpoints:  endpoints,\n\t\topts:       options,\n\t}\n}\n\nfunc validateSubscriber(sub server.Subscriber) error {\n\ttyp := reflect.TypeOf(sub.Subscriber())\n\tvar argType reflect.Type\n\n\tif typ.Kind() == reflect.Func {\n\t\tname := \"Func\"\n\t\tswitch typ.NumIn() {\n\t\tcase 2:\n\t\t\targType = typ.In(1)\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"subscriber %v takes wrong number of args: %v required signature %s\", name, typ.NumIn(), subSig)\n\t\t}\n\t\tif !isExportedOrBuiltinType(argType) {\n\t\t\treturn fmt.Errorf(\"subscriber %v argument type not exported: %v\", name, argType)\n\t\t}\n\t\tif typ.NumOut() != 1 {\n\t\t\treturn fmt.Errorf(\"subscriber %v has wrong number of outs: %v require signature %s\",\n\t\t\t\tname, typ.NumOut(), subSig)\n\t\t}\n\t\tif returnType := typ.Out(0); returnType != typeOfError {\n\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","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/server/grpc/subscriber.go#L107-L143","documentation":"The go-micro gRPC server validates every subscriber registered via Subscribe(). A plain-function subscriber must have the exact signature func(context.Context, interface{}) error — i.e. exactly 2 inputs. This error is thrown when the reflect type check in validateSubscriber sees NumIn() != 2, so the framework refuses to register the handler because it could never be invoked correctly at dispatch time.","triggerScenarios":"Calling server.Subscribe(topic, fn) where fn is a func literal with 0, 1, or 3+ input parameters, e.g. func(msg *pb.Event) error (1 arg, missing ctx) or func(ctx context.Context, msg *pb.Event, extra string) error (3 args).","commonSituations":"Copy-pasting a handler written for another framework that passes only the message; adding a helper parameter to a working handler; using a method-style handler signature as a bare func; refactoring that swapped argument order or dropped context.","solutions":["Change the function to exactly func(ctx context.Context, msg *YourType) error (2 inputs).","If you only need the payload, keep 2 args anyway — context is always first; ignore ctx if unused (use _ as the name).","If you intended a multi-method subscriber, register a struct with methods taking (ctx context.Context, msg *T) error instead of a bare func.","Use a named wrapper type so the signature mismatch is caught by the compiler rather than at registration."],"exampleFix":"// before\nsrv.Subscribe(\"events\", func(e *pb.Event) error { ... })\n// after\nsrv.Subscribe(\"events\", func(ctx context.Context, e *pb.Event) error { ... })","handlingStrategy":"validation","validationCode":"func validFuncSub(fn interface{}) bool {\n\tt := reflect.TypeOf(fn)\n\tif t == nil || t.Kind() != reflect.Func || t.NumIn() != 2 {\n\t\treturn false\n\t}\n\tctxType := reflect.TypeOf((*context.Context)(nil)).Elem()\n\treturn t.In(0).Implements(ctxType)\n}","typeGuard":"func asEventFunc(fn interface{}) func(context.Context, interface{}) error {\n\tf, ok := fn.(func(context.Context, interface{}) error)\n\tif !ok { return nil }\n\treturn f\n}","tryCatchPattern":null,"preventionTips":["Always use the canonical shape func(ctx context.Context, msg *T) error for func subscribers.","Register handlers at startup and run a smoke test so signature errors surface in CI, not production.","Define named handler types (type EventHandler func(context.Context, *pb.Event) error) to get compile-time checks.","Never add parameters to subscriber funcs; use struct fields or context values instead."],"tags":["go","grpc","subscriber","reflection","handler-signature"],"backgroundTag":"invalid-handler-signature","analyzedSha":"24529f140421a11a33b6999ab7944f2021cfd69c","analyzedAt":"2026-09-01T02:52:24.923Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}