geektutu/7days-golang · error
nil Getter
Error message
nil Getter
What it means
NewGroup panics with "nil Getter" when the getter argument is nil. The Getter is the mandatory cache-miss callback that fetches values from the source of truth (DB, file, etc.), so a Group without one can never resolve a miss; the library fails fast at construction instead of returning an error later. This is a deliberate programming-error panic, not a runtime failure.
Source
Thrown at gee-cache/day3-http-server/geecache/geecache.go:37
}
// A GetterFunc implements Getter with a function.
type GetterFunc func(key string) ([]byte, error)
// Get implements Getter interface function
func (f GetterFunc) Get(key string) ([]byte, error) {
return f(key)
}
var (
mu sync.RWMutex
groups = make(map[string]*Group)
)
// NewGroup create a new instance of Group
func NewGroup(name string, cacheBytes int64, getter Getter) *Group {
if getter == nil {
panic("nil Getter")
}
mu.Lock()
defer mu.Unlock()
g := &Group{
name: name,
getter: getter,
mainCache: cache{cacheBytes: cacheBytes},
}
groups[name] = g
return g
}
// GetGroup returns the named group previously created with NewGroup, or
// nil if there's no such group.
func GetGroup(name string) *Group {
mu.RLock()
g := groups[name]
mu.RUnlock()View on GitHub (pinned to cf36443821)
Solutions
- Pass a non-nil Getter implementation (e.g. a function wrapped with geecache.GetterFunc) to NewGroup
- Check the code that produces the Getter — ensure it never returns a typed-nil interface value
- If fetching from a DB, define a GetterFunc closure that loads the value, even if it just returns an error
Example fix
// before
var getter geecache.Getter
g := geecache.NewGroup("scores", 2<<20, getter) // panics: nil Getter
// after
g := geecache.NewGroup("scores", 2<<20, geecache.GetterFunc(func(key string) ([]byte, error) {
return loadFromDB(key)
})) Defensive patterns
Strategy: validation
Validate before calling
if getter == nil {
// fail before calling NewGroup, or supply a default
panic("NewGroup requires a non-nil Getter")
}
g := geecache.NewGroup("scores", 2<<20, getter) Type guard
func hasGetter(g geecache.Getter) bool {
return g != nil // beware typed-nil: also assert the underlying value
} Try / catch
// Go panics are not for control flow; use recover only at top level:
func safeNewGroup(name string, bytes int64, getter geecache.Getter) (g *geecache.Group) {
defer func() {
if r := recover(); r == "nil Getter" {
g = geecache.NewGroup(name, bytes, geecache.GetterFunc(func(string) ([]byte, error) {
return nil, errors.New("no loader configured")
}))
}
}()
return geecache.NewGroup(name, bytes, getter)
} Prevention
- Always wrap plain fetch functions with geecache.GetterFunc instead of passing function values directly
- Initialize data sources before constructing cache groups
- Add a startup integration test that builds all groups with real getters
When it happens
Trigger: Calling geecache.NewGroup(name, cacheBytes, nil) — e.g. passing an uninitialized Getter variable, a nil interface from a failed constructor of the real loader, or forgetting the argument entirely.
Common situations: Wiring a cache before the database layer is initialized; a factory function returning a typed-nil Getter interface; refactoring code so the getter variable is shadowed or zero-valued.
Related errors
AI-assisted analysis of geektutu/7days-golang@cf36443821 (2026-09-03).
Data as JSON: /api/errors/ed9039dfe6bb8aeb.
Report an issue: GitHub.