caddyserver/caddy · critical
invalid command name
Error message
invalid command name
What it means
RegisterCommand panics when cmd.Name does not match commandNameRegex (^[a-z0-9]$|^([a-z0-9]+-?[a-z0-9]*)+[a-z0-9]$): lowercase alphanumerics with single hyphens, no leading/trailing hyphen, no uppercase, no underscores. The check keeps CLI subcommand names uniform and shell-friendly.
Source
Thrown at cmd/commands.go:595
// This function should be used in init().
func RegisterCommand(cmd Command) {
commandsMu.Lock()
defer commandsMu.Unlock()
if cmd.Name == "" {
panic("command name is required")
}
if cmd.Func == nil && cmd.CobraFunc == nil {
panic("command function missing")
}
if cmd.Short == "" {
panic("command short string is required")
}
if _, exists := commands[cmd.Name]; exists {
panic("command already registered: " + cmd.Name)
}
if !commandNameRegex.MatchString(cmd.Name) {
panic("invalid command name")
}
defaultFactory.Use(func(rootCmd *cobra.Command) {
rootCmd.AddCommand(caddyCmdToCobra(cmd))
})
commands[cmd.Name] = cmd
}
var commandNameRegex = regexp.MustCompile(`^[a-z0-9]$|^([a-z0-9]+-?[a-z0-9]*)+[a-z0-9]$`)
View on GitHub (pinned to 50e54ee279)
Solutions
- Rename to lowercase-with-hyphens (kebab-case), e.g. 'my-plugin-run'
- Ensure no leading/trailing hyphen and no consecutive hyphens
- Add a unit test in the plugin asserting commandNameRegex.MatchString(name)
Example fix
// before
caddy.RegisterCommand(caddy.Command{Name: "MyPlugin_Run", ...})
// after
caddy.RegisterCommand(caddy.Command{Name: "my-plugin-run", ...}) Defensive patterns
Strategy: validation
Validate before calling
var commandNameRegex = regexp.MustCompile(`^[a-z0-9]$|^([a-z0-9]+-?[a-z0-9]*)+[a-z0-9]$`)
if !commandNameRegex.MatchString(cmd.Name) {
return fmt.Errorf("command name %q must be lowercase kebab-case", cmd.Name)
} Prevention
- Use lowercase kebab-case names with single hyphens only
- Assert regex validity in the plugin's test suite
When it happens
Trigger: Registering a command with a name like 'MyCmd', 'do_thing', '-run', or 'run--fast' from a plugin's init(); the regex fails and the process panics at startup.
Common situations: Porting commands from other ecosystems that allow underscores or camelCase; autogenerated names from constants; hyphen-doubled names from string concatenation.
Related errors
- command already registered: %s
- command short string is required
- module %s is not a precompressor; is %T
- field %s does not exist in %#v
- network type %s is reserved
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/ec67269ae2b355eb.
Report an issue: GitHub.