vitessio/vitess · error

GetFuncForType does not support function types

Error message

GetFuncForType does not support function types

What it means

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.

Source

Thrown at go/viperutil/get_func.go:119

		}
	case reflect.Float64:
		f = func(v *viper.Viper) func(key string) float64 {
			return v.GetFloat64
		}
	case reflect.Complex64:
		f = getComplex[complex64](64)
	case reflect.Complex128:
		f = getComplex[complex128](128)
	case reflect.Array:
		// Even though the code would be extremely similar to slice types, we
		// cannot support arrays because there's no way to write a function that
		// returns, say, [N]int, for some value of N which we only know at
		// runtime.
		panic("GetFuncForType does not support array types")
	case reflect.Chan:
		panic("GetFuncForType does not support channel types")
	case reflect.Func:
		panic("GetFuncForType does not support function types")
	case reflect.Interface:
		panic("GetFuncForType does not support interface types (specify a specific implementation type instead)")
	case reflect.Map:
		switch typ.Key().Kind() {
		case reflect.String:
			switch val := typ.Elem(); val.Kind() {
			case reflect.String:
				f = func(v *viper.Viper) func(key string) map[string]string {
					return v.GetStringMapString
				}
			case reflect.Slice:
				switch val.Elem().Kind() {
				case reflect.String:
					f = func(v *viper.Viper) func(key string) map[string][]string {
						return v.GetStringMapStringSlice
					}
				}
			case reflect.Interface:

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Keep functions out of configuration: define them in code and only store function *selection* (a string enum) in config
  2. Split the config struct so func-typed fields live outside the viper-managed portion
  3. If intentional, supply a custom GetFunc through viperutil.Configure that ignores viper and returns the function

Example fix

// before
type Cfg struct { Validator func(string) error }
viperutil.Configure[ Cfg ](v, "cfg")
// after
type Cfg struct { ValidatorName string }
validator := validators[cfg.ValidatorName]
Defensive patterns

Strategy: validation

Validate before calling

if reflect.TypeOf(optionValue).Kind() == reflect.Func {
    return errors.New("func types are not config-representable; store a discriminator string instead")
}

Type guard

func isFuncType[T any]() bool {
    var zero T
    return reflect.ValueOf(zero).Kind() == reflect.Func
}

Prevention

When it happens

Trigger: 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.

Common situations: A developer embeds a callback/handler in a config struct and registers the whole struct, expecting viperutil to skip the func field.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/c062add7c256c7a6. Report an issue: GitHub.