larksuite/cli · error
command set %d for domain %q has no commands
Error message
command set %d for domain %q has no commands
What it means
CompileSets requires every command set to declare at least one command. A set whose Commands slice is empty cannot contribute a runnable command path, so compilation fails with the set index and its domain name. It fails atomically — no partial compilation result is returned.
Source
Thrown at internal/commandhost/compile.go:45
if len(sets) == 0 {
return nil, nil
}
builtins := shortcuts.AllShortcuts()
paths := make(map[string]string, len(builtins))
for _, shortcut := range builtins {
paths[shortcut.Service+" "+shortcut.Command] = "built-in command"
}
existingDomains := businessDomains()
compiled := make([]common.Shortcut, 0)
for setIndex, set := range sets {
domain := command.InspectDomain(set.Domain)
if err := validateDomain(domain, existingDomains); err != nil {
return nil, fmt.Errorf("command set %d: %w", setIndex+1, err)
}
if len(set.Commands) == 0 {
return nil, fmt.Errorf("command set %d for domain %q has no commands", setIndex+1, domain.Name)
}
for commandIndex, declaration := range set.Commands {
definition := command.InspectCommand(declaration)
if string(definition.Metadata.Service) != domain.Name {
return nil, fmt.Errorf("command set %d command %d: Metadata.Service %q does not match domain %q",
setIndex+1, commandIndex+1, definition.Metadata.Service, domain.Name)
}
shortcutPath := string(definition.Metadata.Service) + " " + definition.Metadata.Command
if owner, duplicate := paths[shortcutPath]; duplicate {
return nil, fmt.Errorf("command set %d command %d: command path %q conflicts with %s",
setIndex+1, commandIndex+1, shortcutPath, owner)
}
shortcut, err := compileCommand(definition)
if err != nil {
return nil, fmt.Errorf("command set %d command %d (%s): %w", setIndex+1, commandIndex+1, shortcutPath, err)
}
paths[shortcutPath] = fmt.Sprintf("command set %d command %d", setIndex+1, commandIndex+1)
compiled = append(compiled, shortcut)View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Add at least one command declaration to the set's Commands slice
- Remove the set registration entirely if the domain has no commands yet
- Check whether build-tag or config filtering emptied the slice unintentionally
Example fix
// before
sets := []common.ShortcutSet{{Domain: myDomain}} // no commands
// after
sets := []common.ShortcutSet{{Domain: myDomain, Commands: []common.CommandDeclaration{myCmd}}}
Defensive patterns
Strategy: validation
Validate before calling
// before CompileSets:
for i, s := range sets {
if len(s.Commands) == 0 { return fmt.Errorf("set %d (%v) declares no commands", i+1, s.Domain) }
} Try / catch
if _, err := commandhost.CompileSets(sets); err != nil {
return fmt.Errorf("shortcut registration failed: %w", err) // surfaces set index + domain
} Prevention
- Assert len(Shortcuts()) > 0 in each shortcuts package test
- Avoid conditional filtering that can empty the command list
- Register a placeholder-free set only when commands exist
When it happens
Trigger: Registering common.ShortcutSet with a valid Domain but zero entries in Commands; building the slice conditionally such that all commands are filtered out before CompileSets runs.
Common situations: A new shortcuts package stubbed with an empty Shortcuts() list; feature-flag filtering that removes every command; refactoring that renamed command constructors leaving the slice empty.
Related errors
- command set %d: %w
- command set %d command %d: Metadata.Service %q does not matc
- command set %d command %d: command path %q conflicts with %s
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/ca2d26fb52f93e86.
Report an issue: GitHub.