{"record":{"id":"7c445ed64742f866","repo":"kataras/iris","slug":"bad-value-function-has-invalid-number-of-output-a","errorCode":null,"errorMessage":"bad value: function has invalid number of output arguments: %v","messagePattern":"bad value: function has invalid number of output arguments: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"hero/dependency.go","lineNumber":302,"sourceCode":"\t\t}\n\n\t\t// fallback to structure.\n\t\treturn fromStructValue(v.Call(nil)[0], dest)\n\t}\n\n\tif numOut == 0 {\n\t\tpanic(\"bad value: function has zero outputs\")\n\t}\n\n\tif numOut == 2 && !isError(typ.Out(1)) {\n\t\tpanic(\"bad value: second output should be an error\")\n\t}\n\n\tif numOut > 2 {\n\t\t// - at least one output value\n\t\t// - maximum of two output values\n\t\t// - second output value should be a type of error.\n\t\tpanic(fmt.Sprintf(\"bad value: function has invalid number of output arguments: %v\", numOut))\n\t}\n\n\tvar handler DependencyHandler\n\n\tfirstIsContext := isContext(typ.In(0))\n\tsecondIsInput := numIn == 2 && typ.In(1) == inputTyp\n\tonlyContext := (numIn == 1 && firstIsContext) || (numIn == 2 && firstIsContext && typ.IsVariadic())\n\n\tif onlyContext || (firstIsContext && secondIsInput) {\n\t\thandler = handlerFromFunc(v, typ)\n\t}\n\n\tif handler == nil {\n\t\treturn false\n\t}\n\n\tdest.DestType = typ.Out(0)\n\tdest.Handle = handler","sourceCodeStart":284,"sourceCodeEnd":320,"githubUrl":"https://github.com/kataras/iris/blob/7bedaf55a0b64bbb2248a5845a2c60d81a30996a/hero/dependency.go#L284-L320","documentation":"Dependency functions may return at most two values: the dependency (optionally plus an error). Any function returning three or more values cannot be mapped to a single dependency and panics.","triggerScenarios":"Registering funcs like func() (A, B, error) or func(cfg) (A, B, C) via c.Register/NewDependency.","commonSituations":"Go idiom of multi-return factories used directly as a dependency; returning the dependency plus metrics/clients alongside error; gRPC-style (resp, err) wrapped further.","solutions":["Reduce outputs to (T) or (T, error).","Bundle multiple outputs into one struct: type Deps struct{ A A; B B } and return (Deps, error).","Register a thin wrapper closure that collapses the multi-return: c.Register(func() (A, error) { a, b, err := f(); return a, err })."],"exampleFix":"// before\nfunc newClients() (*ClientA, *ClientB, error) { ... }\nc.Register(newClients)\n// after\ntype Clients struct { A *ClientA; B *ClientB }\nfunc newClients() (*Clients, error) { ... }\nc.Register(newClients)","handlingStrategy":"validation","validationCode":"func outCountOK(fn any) bool { n := reflect.TypeOf(fn).NumOut(); return n == 1 || n == 2 }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Cap dependency funcs at (T) or (T, error).","Bundle multi-results into one struct.","Wrap multi-return libraries APIs in single-result closures."],"tags":["dependency-injection","function-signature","panic","too-many-returns"],"backgroundTag":"invalid-dependency-signature","analyzedSha":"7bedaf55a0b64bbb2248a5845a2c60d81a30996a","analyzedAt":"2026-08-30T20:38:16.250Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}