vitessio/vitess · error
no default GetFunc for type %T; call Configure with a custom
Error message
no default GetFunc for type %T; call Configure with a custom GetFunc
What it means
After checking all supported reflect kinds, GetFuncForType[T] falls back to a registry of default GetFuncs keyed by type. If the concrete type T has no registered default (and Configure was not called with a custom GetFunc), it panics 'no default GetFunc for type %T'. This is the catch-all for types outside both the kind switch and the registry.
Source
Thrown at go/viperutil/get_func.go:181
case reflect.Struct:
switch typ {
case reflect.TypeFor[time.Time]():
f = func(v *viper.Viper) func(key string) time.Time {
return v.GetTime
}
default:
f2 := unmarshalFunc[*T]()
f = func(v *viper.Viper) func(key string) T {
getPointer := f2(v)
return func(key string) T {
return *getPointer(key)
}
}
}
}
if f == nil {
panic(fmt.Sprintf("no default GetFunc for type %T; call Configure with a custom GetFunc", t))
}
return f.(func(v *viper.Viper) func(key string) T)
}
func unmarshalFunc[T any]() func(v *viper.Viper) func(key string) T {
return func(v *viper.Viper) func(key string) T {
return func(key string) T {
t := new(T)
_ = v.UnmarshalKey(key, t) // TODO: panic on this error
return *t
}
}
}
func getCastedInt[T int8 | int16]() func(v *viper.Viper) func(key string) T {
return func(v *viper.Viper) func(key string) T {
return func(key string) T {
return T(v.GetInt(key))View on GitHub (pinned to 01a25a7d17)
Solutions
- Call viperutil.Configure with an explicit GetFunc for the type (e.g. viper.GetString / v.GetDuration / UnmarshalKey based)
- Use the dedicated typed helpers that already exist (e.g. viperutil.ConfigureAndGet[time.Duration] only if registered — otherwise supply GetFunc: v.GetDuration)
- Register a package-level default for the type in get_func.go if it is broadly useful
Example fix
// before
viperutil.Configure("timeout", viperutil.Options[time.Duration]{}) // panics
// after
viperutil.Configure("timeout", viperutil.Options[time.Duration]{ GetFunc: func(v *viper.Viper) func(string) time.Duration { return v.GetDuration } }) Defensive patterns
Strategy: validation
Validate before calling
// Verify the type has a default before relying on zero-value Options
var zero T
switch any(zero).(type) {
case string, bool, int, int8, int16, int32, int64,
uint, uint8, uint16, uint32, uint64, float32, float64:
// ok, has default
default:
// slices/maps and registered types only — provide GetFunc otherwise
}
Type guard
func hasDefaultGetFunc[T any]() bool {
_, ok := defaultGetFuncs[reflect.TypeOf(new(T)).Elem()]
return ok
} Try / catch
func configureSafe[T any](v *viper.Viper, key string, getFunc func(*viper.Viper) func(string) T) T {
defer func() {
if r := recover(); r != nil {
log.Fatalf("viperutil: type %T needs an explicit GetFunc: %v", *new(T), r)
}
}()
return viperutil.ConfigureAndGet[T](v, key)
} Prevention
- Never rely on the zero value of viperutil.Options for non-primitive types — always set GetFunc unless the type is a known default
- Check the registry/default kind switch in get_func.go before adding a new option type
- Add a startup smoke test that configures every option so the panic surfaces in CI, not production
When it happens
Trigger: Requesting a getter for a type like time.Duration, net.Addr, or a custom struct without registering a default GetFunc, and calling viperutil.Configure with GetFunc: nil (zero-value Options).
Common situations: A developer relies on the zero value of viperutil.Options (GetFunc nil) assuming their type has a built-in default; only a handful of types (string, bool, ints, floats, slices, string-keyed maps, registered specials) do.
Related errors
- GetFuncForType does not support array types
- GetFuncForType does not support channel types
- GetFuncForType does not support function types
- GetFuncForType does not support interface types (specify a s
- cannot Notify after starting to watch a config
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/c1a8cad6f0768ab8.
Report an issue: GitHub.