{"record":{"id":"c062add7c256c7a6","repo":"vitessio/vitess","slug":"getfuncfortype-does-not-support-function-types","errorCode":null,"errorMessage":"GetFuncForType does not support function types","messagePattern":"GetFuncForType does not support function types","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/viperutil/get_func.go","lineNumber":119,"sourceCode":"\t\t}\n\tcase reflect.Float64:\n\t\tf = func(v *viper.Viper) func(key string) float64 {\n\t\t\treturn v.GetFloat64\n\t\t}\n\tcase reflect.Complex64:\n\t\tf = getComplex[complex64](64)\n\tcase reflect.Complex128:\n\t\tf = getComplex[complex128](128)\n\tcase reflect.Array:\n\t\t// Even though the code would be extremely similar to slice types, we\n\t\t// cannot support arrays because there's no way to write a function that\n\t\t// returns, say, [N]int, for some value of N which we only know at\n\t\t// runtime.\n\t\tpanic(\"GetFuncForType does not support array types\")\n\tcase reflect.Chan:\n\t\tpanic(\"GetFuncForType does not support channel types\")\n\tcase reflect.Func:\n\t\tpanic(\"GetFuncForType does not support function types\")\n\tcase reflect.Interface:\n\t\tpanic(\"GetFuncForType does not support interface types (specify a specific implementation type instead)\")\n\tcase reflect.Map:\n\t\tswitch typ.Key().Kind() {\n\t\tcase reflect.String:\n\t\t\tswitch val := typ.Elem(); val.Kind() {\n\t\t\tcase reflect.String:\n\t\t\t\tf = func(v *viper.Viper) func(key string) map[string]string {\n\t\t\t\t\treturn v.GetStringMapString\n\t\t\t\t}\n\t\t\tcase reflect.Slice:\n\t\t\t\tswitch val.Elem().Kind() {\n\t\t\t\tcase reflect.String:\n\t\t\t\t\tf = func(v *viper.Viper) func(key string) map[string][]string {\n\t\t\t\t\t\treturn v.GetStringMapStringSlice\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tcase reflect.Interface:","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/viperutil/get_func.go#L101-L137","documentation":"GetFuncForType[T] cannot produce a default getter for function-typed configuration values. A func cannot be expressed in config files/env vars, so reflect.Func kinds trigger a panic to force the developer to handle the type explicitly.","triggerScenarios":"Calling viperutil.Configure/GetFuncForType with a func type as the generic parameter (e.g. func(string) error), or registering a settings struct option whose field type is a function that viperutil tries to resolve.","commonSituations":"A developer embeds a callback/handler in a config struct and registers the whole struct, expecting viperutil to skip the func field.","solutions":["Keep functions out of configuration: define them in code and only store function *selection* (a string enum) in config","Split the config struct so func-typed fields live outside the viper-managed portion","If intentional, supply a custom GetFunc through viperutil.Configure that ignores viper and returns the function"],"exampleFix":"// before\ntype Cfg struct { Validator func(string) error }\nviperutil.Configure[ Cfg ](v, \"cfg\")\n// after\ntype Cfg struct { ValidatorName string }\nvalidator := validators[cfg.ValidatorName]","handlingStrategy":"validation","validationCode":"if reflect.TypeOf(optionValue).Kind() == reflect.Func {\n    return errors.New(\"func types are not config-representable; store a discriminator string instead\")\n}","typeGuard":"func isFuncType[T any]() bool {\n    var zero T\n    return reflect.ValueOf(zero).Kind() == reflect.Func\n}","tryCatchPattern":null,"preventionTips":["Keep func-typed fields out of viper-managed structs","Store behavior selectors (strings/enums) in config and map them to functions in code","If a custom GetFunc supplies the function deliberately, set it explicitly in Configure"],"tags":["go","viper","config","generics","panic"],"backgroundTag":"unsupported-config-type","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}