{"record":{"id":"12d02adec2ea2088","repo":"larksuite/cli","slug":"s-alias-s-for-s-conflicts-with-registered-f","errorCode":null,"errorMessage":"%s alias --%s for --%s conflicts with registered flag --%s after normalization","messagePattern":"(.+?) alias --(.+?) for --(.+?) conflicts with registered flag --(.+?) after normalization","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/flagalias/flagalias.go","lineNumber":103,"sourceCode":"\t\tcanonical := canonicalFlag.Name\n\t\tif _, exists := seenCanonical[canonical]; exists {\n\t\t\treturn fmt.Errorf(\"%s declares flag aliases for --%s more than once after normalization\", cmd.CommandPath(), canonical)\n\t\t}\n\t\tseenCanonical[canonical] = struct{}{}\n\t\tcanonicalFlags[canonical] = canonicalFlag\n\t\tfor _, alias := range spec.Aliases {\n\t\t\tif err := validateAliasName(alias); err != nil {\n\t\t\t\treturn fmt.Errorf(\"%s alias for --%s: %w\", cmd.CommandPath(), canonical, err)\n\t\t\t}\n\t\t\tnormalized := normalize(alias)\n\t\t\tif normalized == \"\" {\n\t\t\t\treturn fmt.Errorf(\"%s alias --%s for --%s normalizes to an empty name\", cmd.CommandPath(), alias, canonical)\n\t\t\t}\n\t\t\tif normalized == canonical {\n\t\t\t\treturn fmt.Errorf(\"%s declares --%s as an alias of itself (--%s after normalization)\", cmd.CommandPath(), alias, canonical)\n\t\t\t}\n\t\t\tif existing, ok := registered[normalized]; ok {\n\t\t\t\treturn fmt.Errorf(\"%s alias --%s for --%s conflicts with registered flag --%s after normalization\", cmd.CommandPath(), alias, canonical, existing)\n\t\t\t}\n\t\t\tif existing, ok := acceptedAliases[normalized]; ok {\n\t\t\t\treturn fmt.Errorf(\"%s alias --%s for --%s conflicts with existing alias for --%s after normalization to --%s\", cmd.CommandPath(), alias, canonical, existing, normalized)\n\t\t\t}\n\t\t\tif existing, ok := aliases[normalized]; ok {\n\t\t\t\tif existing == canonical {\n\t\t\t\t\treturn fmt.Errorf(\"%s declares duplicate alias --%s for --%s after normalization to --%s\", cmd.CommandPath(), alias, canonical, normalized)\n\t\t\t\t}\n\t\t\t\treturn fmt.Errorf(\"%s alias --%s maps to both --%s and --%s after normalization to --%s\", cmd.CommandPath(), alias, existing, canonical, normalized)\n\t\t\t}\n\t\t\taliases[normalized] = canonical\n\t\t\tmetadata[canonicalFlag] = append(metadata[canonicalFlag], alias)\n\t\t}\n\t}\n\n\tif len(aliases) == 0 {\n\t\treturn nil\n\t}","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/flagalias/flagalias.go#L85-L121","documentation":"Bind rejects an alias declaration when, after applying the configured normalizer, the alias name is already registered as a real (canonical) flag on the command. This guard keeps the one-alias-to-one-canonical-flag mapping unambiguous: an alias that normalizes onto an existing flag could otherwise silently override or shadow that flag. Bind returns this error during registration, before any parsing happens.","triggerScenarios":"Calling cmd, Bind(...) (directly or via MustBind) where an alias declared for canonical flag X, after normalization (e.g. lowercasing, underscore stripping), equals the name of a different flag already registered on the same Cobra command, so registered[normalized] matches a name other than the canonical target.","commonSituations":"Configuring aliases like --log-level for --logLevel with a normalizer that lowercases names while a native --log-level flag already exists; renaming a canonical flag in a new version while keeping the old name as an alias; two teams independently registering flags on a shared command.","solutions":["Remove or rename the alias so its normalized form no longer collides with the registered flag name","Register the colliding name as the canonical flag instead of an alias, and drop the duplicate native flag","Change the normalizer so alias and flag names no longer converge to the same value","Split the flags across different commands/subcommands if both names are genuinely needed"],"exampleFix":"// before\nBind(cmd, Alias(\"verbose\", \"Verbose\")) // with lowercasing normalizer and existing --verbose flag\n// after\nBind(cmd, Alias(\"v\", \"Verbose\"))","handlingStrategy":"validation","validationCode":"func checkAliasConflict(cmd *cobra.Command, aliases []flagalias.Alias, norm func(string) string) error {\n\tregistered := map[string]bool{}\n\tfor _, f := range cmd.Flags() { registered[f.Name] = true }\n\tseen := map[string]string{}\n\tfor _, a := range aliases {\n\t\tn := norm(a.Alias)\n\t\tif registered[n] && n != norm(a.Canonical) {\n\t\t\treturn fmt.Errorf(\"alias %q conflicts with registered flag --%s\", n, n)\n\t\t}\n\t\tseen[n] = a.Canonical\n\t}\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":"if err := flagalias.MustBind(cmd, aliases...); err != nil {\n\tvar conflict *flagalias.ConflictError\n\tif errors.As(err, &conflict) { log.Fatalf(\"fix alias table: %v\", err) }\n\treturn err\n}","preventionTips":["Run the same normalization on aliases and canonical names and diff against cmd.Flags() in a unit test","Keep alias tables in one place and deduplicate before Bind","Add a startup-time Bind call in tests so conflicts fail CI, not runtime"],"tags":["go","cli","flag-alias","flag-registration"],"backgroundTag":"flag-alias-conflict","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}