micro/go-micro · error

Cannot use two forms of the same flag: <name> <ff.Name>

Error message

Cannot use two forms of the same flag: <name> <ff.Name>

What it means

The CLI config source normalizes flag names (e.g. converting hyphens/underscores or camelCase variants). This error fires when the same flag is registered/visited twice in different textual forms during normalization, which would make the merged config ambiguous. It's a programming/configuration error in the flag set, not a runtime failure.

Source

Thrown at config/source/cli/util.go:34

	}
}

func normalizeFlags(flags []cli.Flag, set *flag.FlagSet) error {
	visited := make(map[string]bool)
	set.Visit(func(f *flag.Flag) {
		visited[f.Name] = true
	})
	for _, f := range flags {
		parts := f.Names()
		if len(parts) == 1 {
			continue
		}
		var ff *flag.Flag
		for _, name := range parts {
			name = strings.Trim(name, " ")
			if visited[name] {
				if ff != nil {
					return errors.New("Cannot use two forms of the same flag: " + name + " " + ff.Name)
				}
				ff = set.Lookup(name)
			}
		}
		if ff == nil {
			continue
		}
		for _, name := range parts {
			name = strings.Trim(name, " ")
			if !visited[name] {
				copyFlag(name, ff, set)
			}
		}
	}
	return nil
}

View on GitHub (pinned to 24529f1404)

Solutions

  1. Remove the duplicate flag registration so each canonical flag name exists only once (keep either "my-flag" or "my_flag", not both).
  2. If aliases are needed intentionally, register them via the flag package's alias mechanism rather than as separate flags.
  3. Audit flag definitions for names that collide after normalization (lowercase, trimmed, separators collapsed) before building the source.
  4. Pin or update the config library if a dependency auto-generates conflicting aliases (check vendor changelog).

Example fix

// before
flag.String("db-host", "", "host")
flag.String("db_host", "", "host") // collides after normalization
// after
flag.String("db-host", "", "host") // single canonical form only
Defensive patterns

Strategy: validation

Validate before calling

func flagsCollide(names []string) bool {
    seen := map[string]bool{}
    for _, n := range names {
        k := strings.ReplaceAll(strings.ToLower(n), "_", "-")
        if seen[k] { return true }
        seen[k] = true
    }
    return false
}

Prevention

When it happens

Trigger: Registering two flags that normalize to the same canonical name (e.g. "my-flag" and "my_flag" or "MyFlag"), both marked as visited while normalizeFlags walks the flag set; NewSource then rejects the ambiguous set.

Common situations: Mixed conventions after merging codebases where one team used hyphens and another underscores; a wrapper library auto-registering aliases for every flag; defining both a shorthand-backed long flag and its long form separately.

Related errors


AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01). Data as JSON: /api/errors/2e0d1cde58e0a2bf. Report an issue: GitHub.