{"record":{"id":"63098f0a2c74edb3","repo":"vitessio/vitess","slug":"duplicate-status-func-registered","errorCode":null,"errorMessage":"duplicate status func registered: ","messagePattern":"duplicate status func registered: ","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/servenv/status.go","lineNumber":199,"sourceCode":"func (sp *statusPage) reset() {\n\tsp.mu.Lock()\n\tdefer sp.mu.Unlock()\n\n\tsp.sections = nil\n\tsp.tmpl = template.Must(sp.reparse(nil))\n\tsp.funcMap = make(template.FuncMap)\n}\n\nfunc (sp *statusPage) addStatusFuncs(fmap template.FuncMap) {\n\tsp.mu.Lock()\n\tdefer sp.mu.Unlock()\n\n\tfor name, fun := range fmap {\n\t\tif !strings.HasPrefix(name, \"github_com_vitessio_vitess_\") {\n\t\t\tpanic(\"status func registered without proper prefix, need github_com_vitessio_vitess_:\" + name)\n\t\t}\n\t\tif _, ok := sp.funcMap[name]; ok {\n\t\t\tpanic(\"duplicate status func registered: \" + name)\n\t\t}\n\t\tsp.funcMap[name] = fun\n\t}\n}\n\nfunc (sp *statusPage) addStatusPart(banner, fragment string, f func() any) {\n\tsp.mu.Lock()\n\tdefer sp.mu.Unlock()\n\n\tsecs := append(sp.sections, section{\n\t\tBanner:   banner,\n\t\tFragment: fragment,\n\t\tF:        f,\n\t})\n\n\tvar err error\n\tsp.tmpl, err = sp.reparse(secs)\n\tif err != nil {","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/servenv/status.go#L181-L217","documentation":"The status page keeps one template func map; registering a func under a name that is already present would overwrite an existing status function, so addStatusFuncs panics on the duplicate name (after the prefix check).","triggerScenarios":"Calling servenv.AddStatusFuncs twice with FuncMaps containing the same fully-prefixed name — e.g. two packages registering 'github_com_vitessio_vitess Durations'-style helpers under identical keys.","commonSituations":"Two vitess packages that both register a common helper name on the status page; importing a new package whose init() registers a name you already registered; tests registering the same func repeatedly.","solutions":["Rename your status func with a more specific suffix to make the name unique","Remove the duplicate AddStatusFuncs call or make registration idempotent (register once)","Check which packages call AddStatusFuncs in your binary and deduplicate names across them"],"exampleFix":"// before\nAddStatusFuncs(tmpl.FuncMap{\"github_com_vitessio_vitess_stats\": f}) // twice\n// after\nAddStatusFuncs(tmpl.FuncMap{\"github_com_vitessio_vitess_mystats\": f})","handlingStrategy":"validation","validationCode":"func uniqueNames(fmap template.FuncMap) error {\n\tseen := map[string]bool{}\n\tfor name := range fmap { if seen[name] { return fmt.Errorf(\"duplicate %s\", name) }; seen[name] = true }\n\treturn nil\n} // run before AddStatusFuncs","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep a single registration point for status funcs per binary","Suffix func names with the owning package to guarantee uniqueness","Review newly imported packages' init() for AddStatusFuncs calls"],"tags":["go","panic","servenv","status-page","duplicate-registration"],"backgroundTag":"duplicate-key-registration","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}