vitessio/vitess · critical
trying to add to missing group %v
Error message
trying to add to missing group %v
What it means
vtctl's addCommand registers a command under a named command group by linear scan; if no group with that name exists it panics. This is an init-time programming error — the group must be created with addCommandGroup before commands are added to it.
Source
Thrown at go/vt/vtctl/vtctl.go:770
// `commands` => refers to `commandHelp` => refers to `PrintAllCommands` => refers to `commands`
addCommand("Generic", command{
name: "Help",
method: commandHelp,
params: "[command name]",
help: "Prints the list of available commands, or help on a specific command.",
})
}
func addCommand(groupName string, c command) {
commandsMutex.Lock()
defer commandsMutex.Unlock()
for i, group := range commands {
if group.name == groupName {
commands[i].commands = append(commands[i].commands, c)
return
}
}
panic(fmt.Errorf("trying to add to missing group %v", groupName))
}
func addCommandGroup(groupName string) {
commandsMutex.Lock()
defer commandsMutex.Unlock()
commands = append(commands, commandGroup{
name: groupName,
})
}
func fmtMapAwkable(m map[string]string) string {
pairs := make([]string, len(m))
i := 0
for k, v := range m {
pairs[i] = fmt.Sprintf("%v: %q", k, v)
i++
}
sort.Strings(pairs)View on GitHub (pinned to 01a25a7d17)
Solutions
- Add (or restore) `addCommandGroup("<groupName>")` before the addCommand call in the init order.
- Fix the groupName string typo so it matches an existing registered group.
- Register the command under an existing group instead of inventing a new one.
Example fix
// before
func init() {
addCommand("mystuff", myCommand)
}
// after
func init() {
addCommandGroup("mystuff")
addCommand("mystuff", myCommand)
} Defensive patterns
Strategy: validation
Validate before calling
// Go, at development time — ensure the group exists before adding a command
func registerCommand(group string, c *command) {
for _, g := range commands {
if g.name == group {
addCommand(group, c)
return
}
}
addCommandGroup(group)
addCommand(group, c)
} Type guard
func groupExists(groupName string) bool {
for _, g := range commands {
if g.name == groupName {
return true
}
}
return false
} Try / catch
// This is a panic during init(); guard it in tests
deferr := func() {
if r := recover(); r != nil {
t.Fatalf("vtctl command registration panicked: %v", r)
}
}
defer deferr()
registerTestCommands() Prevention
- Always pair new addCommand calls with an addCommandGroup call earlier in the same init().
- Add an init-order unit test that registers all command groups.
- Search for addCommandGroup when renaming a command group.
When it happens
Trigger: A developer adds a new `addCommand("somegroup", ...)` call in an init() function without a matching earlier `addCommandGroup("somegroup")`. Since it runs at package init, the process panics immediately at startup.
Common situations: Adding a new vtctl command during development and forgetting to register its group; renaming a command group in one place but not the other; merge conflicts dropping an addCommandGroup line.
Related errors
- collision in caseInsensitiveTable
- keyword %q must be lowercase in table
- this command panics on purpose
- failed to load flag for %s: %w
- uncaught panic: %v
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/7cb617c50a79ab8b.
Report an issue: GitHub.