{"record":{"id":"19a988ff727a7368","repo":"kataras/iris","slug":"bad-value-function-has-zero-outputs","errorCode":null,"errorMessage":"bad value: function has zero outputs","messagePattern":"bad value: function has zero outputs","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"hero/dependency.go","lineNumber":291,"sourceCode":"\ttyp := v.Type()\n\tnumIn := typ.NumIn()\n\tnumOut := typ.NumOut()\n\n\tif numIn == 0 {\n\t\t// it's an empty function, that must return a structure.\n\t\tif numOut != 1 {\n\t\t\tfirstOutType := indirectType(typ.Out(0))\n\t\t\tif firstOutType.Kind() != reflect.Struct && firstOutType.Kind() != reflect.Interface {\n\t\t\t\tpanic(fmt.Sprintf(\"bad value: function has zero inputs: empty input function must output a single value but got: length=%v, type[0]=%s\", numOut, firstOutType.String()))\n\t\t\t}\n\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())","sourceCodeStart":273,"sourceCodeEnd":309,"githubUrl":"https://github.com/kataras/iris/blob/7bedaf55a0b64bbb2248a5845a2c60d81a30996a/hero/dependency.go#L273-L309","documentation":"A dependency function must return at least one value — the dependency itself. A function with zero return values provides nothing the container can inject, so fromFunc panics.","triggerScenarios":"Registering a func(...) with no return values, e.g. func(cfg *Config) { ... } that only performs side effects, via c.Register / NewDependency.","commonSituations":"Passing an initializer/setup function (which mutates globals) instead of a factory function; accidentally registering a method that returns nothing; after a refactor removed the return value.","solutions":["Add a return value: have the function return the dependency (and optionally an error).","If the function is purely for side effects, run it yourself and register its result instead.","Convert: func(cfg *Config) { svc = build(cfg) } → func(cfg *Config) *Svc { return build(cfg) } and register that."],"exampleFix":"// before\nfunc setup(cfg *Config) { /* no return */ }\nc.Register(setup)\n// after\nfunc setup(cfg *Config) *App { return buildApp(cfg) }\nc.Register(setup)","handlingStrategy":"validation","validationCode":"func hasOutput(fn any) bool { return reflect.TypeOf(fn).NumOut() > 0 }","typeGuard":null,"tryCatchPattern":"func() { defer func() { if r := recover(); r != nil { log.Printf(\"bad dependency: %v\", r) } }()\n\tc.Register(fn) }()","preventionTips":["Never register side-effect-only functions.","Every dependency func must return the value it provides.","Code-review factory signatures: (inputs) -> (T) or (T, error)."],"tags":["dependency-injection","function-signature","panic","no-return"],"backgroundTag":"invalid-dependency-signature","analyzedSha":"7bedaf55a0b64bbb2248a5845a2c60d81a30996a","analyzedAt":"2026-08-30T20:38:16.250Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}