vitessio/vitess · error
You've already registered a function
Error message
You've already registered a function
What it means
stats.varGroup.register panics if a NewVarHook is registered more than once for the same var group. The hook is a process-wide singleton (e.g. stats.NewVarHook or package-level registration), so a second registration means two libraries are fighting over var creation callbacks. It also panics on a nil hook.
Source
Thrown at go/stats/export.go:84
}
// StatsAllStr is the consolidated name if a dimension gets combined.
const StatsAllStr = "all"
// NewVarHook is the type of a hook to export variables in a different way
type NewVarHook func(name string, v expvar.Var)
type varGroup struct {
sync.Mutex
vars map[string]expvar.Var
newVarHook NewVarHook
}
func (vg *varGroup) register(nvh NewVarHook) {
vg.Lock()
defer vg.Unlock()
if vg.newVarHook != nil {
panic("You've already registered a function")
}
if nvh == nil {
panic("nil not allowed")
}
vg.newVarHook = nvh
// Call hook on existing vars because some might have been
// created before the call to register
for k, v := range vg.vars {
nvh(k, v)
}
vg.vars = nil
}
func (vg *varGroup) publish(name string, v expvar.Var) {
if isVarDropped(name) {
return
}
vg.Lock()View on GitHub (pinned to 01a25a7d17)
Solutions
- Register the hook exactly once per process — guard with a sync.Once or a package-level 'registered' flag
- Check which package already registers the hook and remove or consolidate the duplicate registration
- In tests, reset/isolate via the stats package's test helpers instead of re-registering
Example fix
// before
stats.RegisterNewVarHook(hook) // called in two packages -> panics
// after
var once sync.Once
func registerHook() {
once.Do(func() { stats.RegisterNewVarHook(hook) })
} Defensive patterns
Strategy: validation
Validate before calling
var hookOnce sync.Once
func ensureHook() {
hookOnce.Do(func() { stats.RegisterNewVarHook(hook) })
} Prevention
- Register the NewVarHook in exactly one place (e.g. main or a single init)
- Use sync.Once for hook registration
- Audit test packages for competing init()-time registrations
When it happens
Trigger: Calling stats.RegisterNewVarHook (or vg.register) twice in one process, e.g. two packages/tests both installing a hook, or an init() that runs again due to duplicate wiring in tests.
Common situations: Test binaries importing multiple packages that each call the hook registration in init(); integrating a new observability library while an existing one already registered the hook; accidental double-invocation in setup code.
Related errors
- CountersWithMultiLabels: wrong number of values in Add
- CountersWithMultiLabels: wrong number of values in Reset
- GaugesWithMultiLabels: wrong number of values in Set
- nil not allowed
- interval too small
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/c7e5232799f302e2.
Report an issue: GitHub.