larksuite/cli · error
%s alias --%s maps to both --%s and --%s after normalization
Error message
%s alias --%s maps to both --%s and --%s after normalization to --%s
What it means
Bind rejects an alias whose normalized name is already bound to a different canonical flag within the same command; the alias would map to two canonical flags at once. This is distinct from the registered-flag conflict: here the name collides with a previously accepted alias, not a native flag. The message lists both canonical targets and the shared normalized name for diagnosis.
Source
Thrown at internal/flagalias/flagalias.go:112
}
normalized := normalize(alias)
if normalized == "" {
return fmt.Errorf("%s alias --%s for --%s normalizes to an empty name", cmd.CommandPath(), alias, canonical)
}
if normalized == canonical {
return fmt.Errorf("%s declares --%s as an alias of itself (--%s after normalization)", cmd.CommandPath(), alias, canonical)
}
if existing, ok := registered[normalized]; ok {
return fmt.Errorf("%s alias --%s for --%s conflicts with registered flag --%s after normalization", cmd.CommandPath(), alias, canonical, existing)
}
if existing, ok := acceptedAliases[normalized]; ok {
return fmt.Errorf("%s alias --%s for --%s conflicts with existing alias for --%s after normalization to --%s", cmd.CommandPath(), alias, canonical, existing, normalized)
}
if existing, ok := aliases[normalized]; ok {
if existing == canonical {
return fmt.Errorf("%s declares duplicate alias --%s for --%s after normalization to --%s", cmd.CommandPath(), alias, canonical, normalized)
}
return fmt.Errorf("%s alias --%s maps to both --%s and --%s after normalization to --%s", cmd.CommandPath(), alias, existing, canonical, normalized)
}
aliases[normalized] = canonical
metadata[canonicalFlag] = append(metadata[canonicalFlag], alias)
}
}
if len(aliases) == 0 {
return nil
}
tracked := make(map[string]*trackedValue, len(canonicalFlags))
for canonical, flag := range canonicalFlags {
tracked[canonical] = ensureTrackedValue(flag)
}
for flag, names := range metadata {
setAliases(flag, append(Aliases(flag), names...))
}
flagSet.SetNormalizeFunc(func(set *pflag.FlagSet, name string) pflag.NormalizedName {
normalized := nameView on GitHub (pinned to 7fd6ef3c07)
Solutions
- Pick distinct alias strings so each normalized name maps to only one canonical flag
- Delete the alias belonging to the deprecated canonical flag
- Unify the two canonical flags into one if they represent the same concept
- Bind the alias groups on separate commands/subcommands
Example fix
// before
Bind(cmd, Alias("dryRun", "DryRun"), Alias("dry-run", "DryRunAll")) // normalizer folds dashes
// after
Bind(cmd, Alias("dryRun", "DryRun"), Alias("dryRunAll", "DryRunAll")) Defensive patterns
Strategy: validation
Validate before calling
func checkOneToOne(aliases []flagalias.Alias, norm func(string) string) error {
m := map[string]string{}
for _, a := range aliases {
n := norm(a.Alias)
if prev, ok := m[n]; ok && prev != a.Canonical {
return fmt.Errorf("alias %q maps to both %s and %s", n, prev, a.Canonical)
}
m[n] = a.Canonical
}
return nil
} Try / catch
if err := flagalias.MustBind(cmd, aliases...); err != nil {
if strings.Contains(err.Error(), "maps to both") {
return fmt.Errorf("alias maps to multiple canonical flags: %w", err)
}
return err
} Prevention
- Keep a one-normalized-alias-to-one-canonical invariant in the alias table
- Remove aliases of deprecated flags when renaming canonical flags
- Verify mappings with a unit test that mirrors Bind's normalization
When it happens
Trigger: Within one Bind call or successive Bind calls on the same command, two aliases with the same normalized form point at different canonical flags, e.g. Alias("dryRun","DryRun") and Alias("dry-run","DryRunAll") where the normalizer converts dashes, so aliases[normalized] exists with existing != canonical.
Common situations: Auto-generated alias sets from two flag families that share naming; renaming a canonical flag and adding an alias that collides with an old family's alias; normalizer introduction in an upgrade that newly merges names.
Related errors
- %s alias --%s for --%s conflicts with existing alias for --%
- %s declares duplicate alias --%s for --%s after normalizatio
- %s alias --%s for --%s conflicts with registered flag --%s a
- name must not be empty
- invalid --param format
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/1f844ad5cac1989b.
Report an issue: GitHub.