micro/go-micro · error
subscriber %v.%v has wrong number of outs: %v require signat
Error message
subscriber %v.%v has wrong number of outs: %v require signature %s
What it means
A valid gRPC subscriber handler must return exactly one value of type error, matching the signature `func(ctx context.Context, msg T) error`. validateSubscriber rejects any method whose number of return values is not exactly 1, reporting the actual count via this error.
Source
Thrown at server/grpc/subscriber.go:156
hdlr := reflect.ValueOf(sub.Subscriber())
name := reflect.Indirect(hdlr).Type().Name()
for m := 0; m < typ.NumMethod(); m++ {
method := typ.Method(m)
switch method.Type.NumIn() {
case 3:
argType = method.Type.In(2)
default:
return fmt.Errorf("subscriber %v.%v takes wrong number of args: %v required signature %s",
name, method.Name, method.Type.NumIn(), subSig)
}
if !isExportedOrBuiltinType(argType) {
return fmt.Errorf("%v argument type not exported: %v", name, argType)
}
if method.Type.NumOut() != 1 {
return fmt.Errorf(
"subscriber %v.%v has wrong number of outs: %v require signature %s",
name, method.Name, method.Type.NumOut(), subSig)
}
if returnType := method.Type.Out(0); returnType != typeOfError {
return fmt.Errorf("subscriber %v.%v returns %v not error", name, method.Name, returnType.String())
}
}
}
return nil
}
func (g *grpcServer) createSubHandler(sb *subscriber, opts server.Options) broker.Handler {
return func(p broker.Event) (err error) {
defer func() {
if r := recover(); r != nil {
g.opts.Logger.Log(logger.ErrorLevel, "panic recovered: ", r)
g.opts.Logger.Log(logger.ErrorLevel, string(debug.Stack()))View on GitHub (pinned to 24529f1404)
Solutions
- Change the handler to return exactly one value of type error: `func (h *h) Handle(ctx context.Context, evt *Event) error`
- If you need to convey results, encode them into the message or use a published response topic instead of extra return values
Example fix
// before
func (h *handler) Handle(ctx context.Context, e *Event) (string, error) { ... }
// after
func (h *handler) Handle(ctx context.Context, e *Event) error { ... } Defensive patterns
Strategy: validation
Validate before calling
func validHandlerOuts(fn interface{}) bool {
return reflect.TypeOf(fn).NumOut() == 1
} Prevention
- Follow the canonical subscriber signature: func(ctx context.Context, msg *T) error
- Never add extra return values to subscriber handlers; return data via messages or topics
- Validate all handlers at startup by registering them immediately rather than lazily
When it happens
Trigger: Registering a subscriber whose method returns zero values (`func (h *h) Handle(evt *Event)`), two values (`(result, error)`), or more than one output.
Common situations: Copying a request/reply service handler style that returns `(resp, error)`; refactoring handlers to also return a value; forgetting the error return entirely.
Related errors
- subscriber %v.%v returns %v not error
- subscriber %v takes wrong number of args: %v required signat
- subscriber %v argument type not exported: %v
- subscriber %v has wrong number of outs: %v require signature
- subscriber %v returns %v not error
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/4d68b91d910cc2ef.
Report an issue: GitHub.