larksuite/cli · error
command set %d command %d: command path %q conflicts with %s
Error message
command set %d command %d: command path %q conflicts with %s
What it means
CompileSets builds the flat list of Shortcut commands from registered command sets. Every compiled command must own a unique 'service command' path; when a second definition produces the same path as one already registered, compilation aborts so an ambiguous route can never reach dispatch.
Source
Thrown at internal/commandhost/compile.go:55
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)
}
}
return compiled, nil
}
// ValidateDeclaration compiles one declaration through the production compiler
// and discards the result. A business test harness calls it so a wrong tag,
// Shape or relation fails in the unit test rather than at CLI startup: executing
// hooks directly exercises none of the compiler's contract checks, which is the
// gap that let a green test ship a command that cannot mount.View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Rename the duplicate definition's Metadata.Command so the path is unique
- Change Metadata.Service on one of the conflicting definitions to a distinct domain
- Search all command set registrations for the path printed in the error and remove the stale duplicate
Example fix
// before
Metadata: command.Metadata{Service: "doc", Command: "create"}
// second set
Metadata: command.Metadata{Service: "doc", Command: "create"}
// after
Metadata: command.Metadata{Service: "doc", Command: "create"}
Metadata: command.Metadata{Service: "doc", Command: "create-from-template"} Defensive patterns
Strategy: validation
Validate before calling
seen := map[string]bool{}
for _, def := range defs {
p := string(def.Metadata.Service) + " " + def.Metadata.Command
if seen[p] { return fmt.Errorf("duplicate command path %q", p) }
seen[p] = true
} Try / catch
compiled, err := commandhost.CompileSets(sets)
if err != nil && strings.Contains(err.Error(), "conflicts with") {
return fmt.Errorf("fix duplicate shortcut registration: %w", err)
} Prevention
- Keep one registry/source of truth for command paths
- Add a compile-time or test assertion that all Metadata.Service+Command pairs are unique
- Never copy a HostDefinition without renaming its Metadata.Command
When it happens
Trigger: Registering two HostDefinitions in (possibly different) command sets whose Metadata.Service plus Metadata.Command collide, e.g. two shortcuts both named 'doc create' or a service value that duplicates a core command's path.
Common situations: Copy-pasting an existing shortcut definition and forgetting to rename it; a plugin/extension contributing a set that overlaps a built-in domain; renaming Metadata.Command in one place but leaving a stale duplicate.
Related errors
- invalid --param format
- unsafe --output-dir
- unknown flag: --{name}
- command set %d command %d (%s): %w
- profile name cannot be empty
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/81baab971929a26c.
Report an issue: GitHub.