larksuite/cli · error

duplicate alias --%s

Error message

duplicate alias --%s

What it means

Aliases within one field must be unique; seenAliases tracks names already registered and a repeated name aborts compilation of the input struct. (Distinct aliases across different fields are a separate concern.)

Source

Thrown at shortcuts/common/typed_compile_args.go:350

		if kind != reflect.Slice && kind != reflect.Array && kind != reflect.Struct && kind != reflect.Map && kind != reflect.Interface {
			return fmt.Errorf("encoding json requires array, object, oneOf, or custom JSON input")
		}
		if isNilCapable(field.valueType) && field.nullable == nil && !field.shapeExplicit && !shapeExplicitlyNullable(field.shape) {
			return fmt.Errorf("nil-capable encoding=json input must declare nullable or nonnullable")
		}
	default:
		return fmt.Errorf("unknown CLI encoding %q", field.cli.Encoding)
	}
	seenAliases := make(map[string]struct{})
	for i, alias := range field.cli.Aliases {
		if !aliasNamePattern.MatchString(alias.Name) {
			return fmt.Errorf("alias[%d] name %q is invalid", i, alias.Name)
		}
		if alias.Name == field.name {
			return fmt.Errorf("alias[%d] duplicates canonical flag --%s", i, field.name)
		}
		if _, duplicate := seenAliases[alias.Name]; duplicate {
			return fmt.Errorf("duplicate alias --%s", alias.Name)
		}
		seenAliases[alias.Name] = struct{}{}
		switch alias.Mode {
		case typedAliasNormalize:
			if alias.Conflict != "" {
				return fmt.Errorf("normalize alias --%s cannot declare Conflict", alias.Name)
			}
			if alias.Deprecated {
				return fmt.Errorf("deprecated alias --%s must use independent mode so Cobra can emit its warning", alias.Name)
			}
		case typedAliasIndependent:
			switch alias.Conflict {
			case typedAliasCanonicalWins, typedAliasErrorIfBoth:
			case typedAliasTrimmedEqualOrError:
				if indirectKind(field.valueType) != reflect.String {
					return fmt.Errorf("trimmed_equal_or_error alias --%s requires string input", alias.Name)
				}
			default:

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Delete the duplicate alias entry, keeping one.
  2. Rename one of the colliding aliases to a distinct valid name.
  3. Grep the tag for the duplicated name to find both occurrences.

Example fix

// before
cli:"alias=ids;alias=identifier;alias=ids"
// after
cli:"alias=ids;alias=identifier"
Defensive patterns

Strategy: validation

Validate before calling

func noDuplicateAliases(aliases []string) error {
	seen := map[string]bool{}
	for _, a := range aliases {
		if seen[a] { return fmt.Errorf("duplicate alias --%s", a) }
		seen[a] = true
	}
	return nil
}

Prevention

When it happens

Trigger: cli tag lists the same alias twice, e.g. cli:"alias=ids;alias=identifiers;alias=ids"; the second occurrence hits the seenAliases map and fails.

Common situations: Merging alias lists from two branches or field copies; mechanically appending aliases without noticing a duplicate.

Related errors


AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04). Data as JSON: /api/errors/5026f7010658b9c8. Report an issue: GitHub.