vitessio/vitess · error
GetFuncForType does not support interface types (specify a s
Error message
GetFuncForType does not support interface types (specify a specific implementation type instead)
What it means
GetFuncForType[T] cannot infer which concrete implementation to construct for an interface-typed value: viper would return raw data with no way to choose the implementing type. It panics with a hint to specify a specific implementation type instead.
Source
Thrown at go/viperutil/get_func.go:121
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:
f = func(v *viper.Viper) func(key string) map[string]any {
return v.GetStringMapView on GitHub (pinned to 01a25a7d17)
Solutions
- Use a concrete type as the generic parameter (e.g. *bytes.Buffer rather than io.Reader) and store it in an interface-typed variable afterward
- Store a discriminator string in config (e.g. implementation name) and map it to a constructor in code
- Pass a custom GetFunc via viperutil.Configure that unmarshals and constructs the right implementation
Example fix
// before r, _ := viperutil.ConfigureAndGet[ io.Reader ](v, "input") // after s, _ := viperutil.ConfigureAndGet[ string ](v, "input-file") r, err := os.Open(s)
Defensive patterns
Strategy: validation
Validate before calling
t := reflect.TypeOf(optionValue)
if t != nil && t.Kind() == reflect.Interface {
return errors.New("specify a concrete implementation type for viperutil options")
} Type guard
func isInterfaceType[T any]() bool {
var zero T
tt := reflect.TypeOf(zero)
return tt != nil && tt.Kind() == reflect.Interface
} Prevention
- Always use concrete types as viperutil generic parameters
- Convert to the interface at the call site after retrieval
- For pluggable behavior, store a name in config and resolve a constructor map in code
When it happens
Trigger: Calling viperutil.Configure/GetFuncForType with an interface type parameter (e.g. io.Reader, net.Addr, or a project interface) instead of a concrete type.
Common situations: A developer models a pluggable config option by its interface type and expects the config layer to pick the implementation from config values.
Related errors
- GetFuncForType does not support array types
- GetFuncForType does not support channel types
- GetFuncForType does not support function types
- no default GetFunc for type %T; call Configure with a custom
- cannot Notify after starting to watch a config
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/2ff72936da63e051.
Report an issue: GitHub.