vitessio/vitess · error
GetFuncForType does not support channel types
Error message
GetFuncForType does not support channel types
What it means
GetFuncForType[T] in go/viperutil refuses channel-typed configuration values. Viper cannot meaningfully Get a channel from file/flag/env config sources, so the function panics on reflect.Chan instead of silently returning a nil or broken channel.
Source
Thrown at go/viperutil/get_func.go:117
return float32(v.GetFloat64(key))
}
}
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
}View on GitHub (pinned to 01a25a7d17)
Solutions
- Remove the channel from the config layer; pass channels through DI/constructor arguments instead
- Configure a primitive or supported type that signals how to construct the channel, and create the channel in code
- Provide a custom GetFunc via Configure only if you genuinely need a channel value from viper (not recommended)
Example fix
// before
ch, _ := viperutil.ConfigureAndGet[ chan struct{} ](v, "shutdown")
// after
ch := make(chan struct{}) // created in code, not config
cfg, _ := viperutil.ConfigureAndGet[ string ](v, "shutdown-mode") Defensive patterns
Strategy: validation
Validate before calling
if reflect.TypeOf(optionValue).Kind() == reflect.Chan {
return errors.New("channels cannot be configured via viper; pass them through code")
} Type guard
func isChannelType[T any]() bool {
var zero T
return reflect.ValueOf(zero).Kind() == reflect.Chan
} Prevention
- Never put chan types in viperutil generic parameters or config structs
- Pass channels via constructor/DI, keep config limited to serializable values
- If you need shutdown signaling config, use a string/enum option and build the channel in code
When it happens
Trigger: Calling viperutil.Configure/GetFuncForType with a type parameter like chan struct{} or <-chan struct{} (e.g. someone registers a notification-channel option).
Common situations: A developer tries to wire an internal signal channel through the config system instead of passing it as a constructor parameter.
Related errors
- GetFuncForType does not support array types
- GetFuncForType does not support function types
- GetFuncForType does not support interface types (specify a s
- 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/bc42cea8873108dd.
Report an issue: GitHub.