larksuite/cli · error

Args field %s (--%s): alias --%s duplicates %s

Error message

Args field %s (--%s): alias --%s duplicates %s

What it means

compileInput tracks all flag names and aliases in allNames and rejects any alias that collides with an already-registered flag, alias, or previously seen name. 'previous' records what claimed the name first (e.g. "--other-flag" or "alias of --x").

Source

Thrown at shortcuts/common/typed_compile_args.go:67

		}
		allNames[field.name] = "--" + field.name
		fieldByName[field.name] = i
		supplement, hasSupplement := supplements[field.name]
		if hasSupplement {
			if err := mergeInputSupplement(field, supplement); err != nil {
				return nil, nil, fmt.Errorf("Args field %s (--%s): %w", field.goName, field.name, err)
			}
			delete(supplements, field.name)
		}
		if field.description == "" {
			return nil, nil, fmt.Errorf("Args field %s (--%s): description is required via doc or InputField.Description", field.goName, field.name)
		}
		if err := validateInputCLI(field); err != nil {
			return nil, nil, fmt.Errorf("Args field %s (--%s): %w", field.goName, field.name, err)
		}
		for _, alias := range field.cli.Aliases {
			if previous, exists := allNames[alias.Name]; exists {
				return nil, nil, fmt.Errorf("Args field %s (--%s): alias --%s duplicates %s", field.goName, field.name, alias.Name, previous)
			}
			allNames[alias.Name] = "alias of --" + field.name
		}
	}
	if len(supplements) > 0 {
		for name := range supplements {
			return nil, nil, fmt.Errorf("Input.Fields references unknown flag --%s", name)
		}
	}
	return fields, fieldByName, nil
}

func collectArgFields(t reflect.Type, parentIndex []int, insideInline bool, out *[]compiledInputField, seenGo map[string]struct{}, supplements map[string]typedInputField) error {
	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)
		if !field.IsExported() {
			if hasAnyTag(field, "flag", "arg", "schema", "cli", "doc", "json") {
				return fmt.Errorf("Args field %s is unexported but declares Typed input tags", field.Name)

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Remove the colliding alias from field.cli.Aliases.
  2. Rename the alias to a unique canonical name not used by any other flag or alias.
  3. If the alias should replace the primary flag, change the flag tag instead of adding an alias.

Example fix

// before
UserID string `flag:"user-id" cli:"aliases=[status]"`
Status string `flag:"status"`
// after
UserID string `flag:"user-id"`
Status string `flag:"status"`
Defensive patterns

Strategy: validation

Validate before calling

func aliasCollides(flags, aliases []string) error {
  set := map[string]bool{}
  for _, f := range flags { set[f] = true }
  for _, a := range aliases {
    if set[a] { return fmt.Errorf("alias --%s collides with a flag", a) }
    set[a] = true
  }
  return nil
}

Prevention

When it happens

Trigger: Adding an alias in field.cli.Aliases that equals another field's flag name, another field's alias, or its own primary flag name, during compileInput.

Common situations: Adding short-form aliases like "-u" or "u" that collide with another flag; copy-pasting alias lists between fields; an alias intended as shorthand that accidentally matches an existing full flag name.

Related errors


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