micro/go-micro · error
subscriber %v has wrong number of outs: %v require signature
Error message
subscriber %v has wrong number of outs: %v require signature %s
What it means
A subscriber function must return exactly one value: error (signature func(context.Context, interface{}) error). validateSubscriber rejects handlers whose return count differs from 1, because the dispatch code (createSubHandler) reads returnValues[0] unconditionally and needs an error to decide ack/retry behavior.
Source
Thrown at server/grpc/subscriber.go:131
}
func validateSubscriber(sub server.Subscriber) error {
typ := reflect.TypeOf(sub.Subscriber())
var argType reflect.Type
if typ.Kind() == reflect.Func {
name := "Func"
switch typ.NumIn() {
case 2:
argType = typ.In(1)
default:
return fmt.Errorf("subscriber %v takes wrong number of args: %v required signature %s", name, typ.NumIn(), subSig)
}
if !isExportedOrBuiltinType(argType) {
return fmt.Errorf("subscriber %v argument type not exported: %v", name, argType)
}
if typ.NumOut() != 1 {
return fmt.Errorf("subscriber %v has wrong number of outs: %v require signature %s",
name, typ.NumOut(), subSig)
}
if returnType := typ.Out(0); returnType != typeOfError {
return fmt.Errorf("subscriber %v returns %v not error", name, returnType.String())
}
} else {
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)View on GitHub (pinned to 24529f1404)
Solutions
- Give the handler exactly one return value of type error.
- If you need to surface results, publish them on another topic or store them — subscribers communicate via errors only.
- If the handler can't fail, still return nil error: func(ctx context.Context, e *T) error { ...; return nil }.
- Move multi-value logic into an inner helper and wrap it in a signature-compliant subscriber.
Example fix
// before
srv.Subscribe("events", func(ctx context.Context, e *pb.Event) (bool, error) { ... })
// after
srv.Subscribe("events", func(ctx context.Context, e *pb.Event) error { ...; return nil }) Defensive patterns
Strategy: validation
Validate before calling
func singleErrorReturn(fn interface{}) bool {
t := reflect.TypeOf(fn)
return t != nil && t.Kind() == reflect.Func && t.NumOut() == 1 &&
t.Out(0) == reflect.TypeOf((*error)(nil)).Elem()
} Prevention
- Subscribers return exactly one value: error — no exceptions.
- Discard intermediate results; publish outcomes on another topic instead.
- Return nil error even for infallible handlers.
- Lint handler registrations with the reflect-based validation helper in tests.
When it happens
Trigger: Registering a func with zero returns (func(ctx context.Context, e *T)) or multiple returns (func(ctx context.Context, e *T) (bool, error)), or a method-style subscriber method on a struct returning something other than exactly one error.
Common situations: Reusing an ordinary service method that returns (result, error) as a subscriber; stripping the error return to 'simplify' the handler; adapting a callback that logs instead of returning errors; converting handlers between frameworks with different conventions.
Related errors
- subscriber %v takes wrong number of args: %v required signat
- subscriber %v returns %v not error
- subscriber %v.%v takes wrong number of args: %v required sig
- subscriber %v argument type not exported: %v
- %v argument type not exported: %v
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/0d25bd841faeaf1b.
Report an issue: GitHub.