{"record":{"id":"864d15587d25508e","repo":"kataras/iris","slug":"bindings-unresolved-no-a-func-type-v","errorCode":null,"errorMessage":"bindings: unresolved: no a func type: %#+v","messagePattern":"bindings: unresolved: no a func type: %#\\+v","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"hero/binding.go","lineNumber":256,"sourceCode":"\t\t}\n\t}\n\n\treturn\n}\n\nfunc isPayloadType(in reflect.Type) bool {\n\tswitch indirectType(in).Kind() {\n\tcase reflect.Struct, reflect.Slice, reflect.Ptr:\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\nfunc getBindingsForFunc(fn reflect.Value, dependencies []*Dependency, disablePayloadAutoBinding bool, paramsCount int) []*binding {\n\tfnTyp := fn.Type()\n\tif !isFunc(fnTyp) {\n\t\tpanic(fmt.Sprintf(\"bindings: unresolved: no a func type: %#+v\", fn))\n\t}\n\n\tn := fnTyp.NumIn()\n\tinputs := make([]reflect.Type, n)\n\tfor i := 0; i < n; i++ {\n\t\tinputs[i] = fnTyp.In(i)\n\t}\n\n\tbindings := getBindingsFor(inputs, dependencies, disablePayloadAutoBinding, paramsCount)\n\tif expected, got := n, len(bindings); expected != got {\n\t\texpectedInputs := \"\"\n\t\tmissingInputs := \"\"\n\t\tfor i, in := range inputs {\n\t\t\tpos := i + 1\n\t\t\ttypName := in.String()\n\t\t\texpectedInputs += fmt.Sprintf(\"\\n  - [%d] %s\", pos, typName)\n\t\t\tfound := false\n\t\t\tfor _, b := range bindings {","sourceCodeStart":238,"sourceCodeEnd":274,"githubUrl":"https://github.com/kataras/iris/blob/7bedaf55a0b64bbb2248a5845a2c60d81a30996a/hero/binding.go#L238-L274","documentation":"This panic comes from hero's dependency-injection container when getBindingsForFunc is asked to build input bindings for a value that is not a function. The library's handler/dependency resolution pipeline only accepts reflect.Value wrappers around func types, so it panics with 'bindings: unresolved: no a func type' to fail fast at registration time rather than at request time.","triggerScenarios":"Calling Container.Handler / hero.Register (which route into makeHandler -> getBindingsForFunc) with a non-func value, e.g. a struct value instead of a struct method value, a nil handler, or passing a plain object where a func was expected; also calling fromDependentFunc with a field that is not a func.","commonSituations":"Typos where a variable holding the handler is shadowed by a non-func value; registering an interface-typed value that is nil; refactoring a handler from a func to a struct method and forgetting to pass the bound method (e.g. passing ctrl instead of ctrl.Handler); upgrading Iris/hero versions where the API now expects a func handler value.","solutions":["Verify the value passed to the container/handler registration is actually a func: pass ctrl.HandlerName (method value), not ctrl.","If it is a variable, check it is not the zero value (nil func or non-func type) before registration.","Use reflect to confirm: reflect.ValueOf(v).Kind() == reflect.Func before registering.","If you intended to register a struct (controller), use the struct registration API (Container.Controller / hero.Struct) instead of the handler API.","If nil, initialize the handler before registration."],"exampleFix":"// before\napp.Party(\"/\").Handler(myController) // myController is a struct, not a func\n// after\napp.Party(\"/\").Handler(myController.ServeHTTP) // pass the method value (a func)","handlingStrategy":"validation","validationCode":"func isFuncHandler(v any) bool {\n    if v == nil { return false }\n    rv := reflect.ValueOf(v)\n    return rv.Kind() == reflect.Func\n}\n// before registering: if !isFuncHandler(handler) { log.Fatalf(\"handler %T is not a func\", handler) }","typeGuard":"func asFuncHandler(v any) (reflect.Value, bool) {\n    rv := reflect.ValueOf(v)\n    if rv.Kind() != reflect.Func { return reflect.Value{}, false }\n    return rv, true\n}","tryCatchPattern":null,"preventionTips":["Always pass method values (ctrl.Handler), not struct values, to handler registration APIs.","Check registered handler variables are non-nil funcs at startup with a startup validation test.","Keep handler registration in one place so a code review can verify every argument is a func.","Write a unit test that registers all handlers; the panic then surfaces in CI, not production."],"tags":["go","reflection","dependency-injection","panic","handler-registration"],"backgroundTag":"non-func-handler-registered","analyzedSha":"7bedaf55a0b64bbb2248a5845a2c60d81a30996a","analyzedAt":"2026-08-30T20:38:16.250Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}