vitessio/vitess · error

nil not allowed

Error message

nil not allowed

What it means

stats.register installs a global variable hook (newVarHook) on a varGroup, and only one hook may ever exist per group. The library panics if the caller passes a nil hook function, since a nil hook would silently disable stats export and break the invariant that every registered var is delivered to the hook.

Source

Thrown at go/stats/export.go:87

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()
	defer vg.Unlock()

	expvar.Publish(name, v)

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Pass a non-nil function to stats.register, even a no-op like func(string, interface{}) {} if you do not need the values yet.
  2. Check the code path that builds the hook function and ensure it is assigned before register is called.
  3. Add an assert/unit test that the hook is non-nil before calling register to fail at the right place.

Example fix

// before
var hook func(string, interface{})
stats.register(hook) // panics: nil not allowed
// after
var hook func(string, interface{}) = func(_ string, _ interface{}) {}
stats.register(hook)
Defensive patterns

Strategy: validation

Validate before calling

if hook == nil {
    hook = func(string, interface{}) {} // or return an error before calling register
}
stats.register(hook)

Prevention

When it happens

Trigger: Calling stats.register(nil) (or the package-level StatsCmdHook/Exporter registration wrappers with a nil function) before any hook has been set.

Common situations: A variable holding the hook function was not yet assigned when registration runs (initialization-order bug); a refactor removed the callback body leaving a nil func; wiring code conditionally skips assigning the hook in some build modes.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/075367e88ec0cbdc. Report an issue: GitHub.