larksuite/cli · error

CLI.ValueSources is declared by both cli tag and…

Error message

CLI.ValueSources is declared by both cli tag and InputField.CLI

What it means

Value sources (flag/file/stdin) were declared both in the cli tag and in InputField.CLI.ValueSources. The compiler rejects the double declaration because sources determine accepted input channels and must be unambiguous.

Solutions

  1. Remove the sources= entry from the cli tag and keep InputField.CLI.ValueSources.
  2. Or drop InputField.CLI.ValueSources if the tag already declares the sources.

Example fix

// before
Data string `flag:"data" cli:"sources=flag,file"` + InputField{CLI: CLI{ValueSources: [...]}}
// after
Data string `flag:"data"` + InputField{CLI: CLI{ValueSources: [...]}}
Defensive patterns

Strategy: validation

Validate before calling

for _, f := range fields {
    if len(f.TagSources) > 0 && len(f.InputSources) > 0 {
        return fmt.Errorf("flag %s: value sources declared twice", f.Name)
    }
}

Prevention

When it happens

Trigger: compileInput -> mergeInputSupplement when len(supplement.CLI.ValueSources) > 0 and len(field.cli.ValueSources) > 0 (parsed from cli tag, e.g. cli:"sources=flag,file").

Common situations: Adding programmatic ValueSources to a field whose cli tag already lists sources, typically during incremental migration from tags to InputField definitions.

Related errors


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

Appendix: source

Thrown at shortcuts/common/typed_compile_args.go:244

	}
	if supplement.Default.Set {
		if field.defaultValue.Set {
			return fmt.Errorf("default is declared by both schema and InputField.Default")
		}
		if field.required {
			return fmt.Errorf("required input cannot declare a default")
		}
		field.defaultValue = supplement.Default
	}
	if len(supplement.CLI.Aliases) > 0 {
		if len(field.cli.Aliases) > 0 {
			return fmt.Errorf("CLI.Aliases is declared by both cli tag and InputField.CLI")
		}
		field.cli.Aliases = append([]typedFlagAlias(nil), supplement.CLI.Aliases...)
	}
	if len(supplement.CLI.ValueSources) > 0 {
		if len(field.cli.ValueSources) > 0 {
			return fmt.Errorf("CLI.ValueSources is declared by both cli tag and InputField.CLI")
		}
		field.cli.ValueSources = append([]typedValueSource(nil), supplement.CLI.ValueSources...)
	}
	if supplement.CLI.Encoding != "" {
		if field.cli.Encoding != "" {
			return fmt.Errorf("CLI.Encoding is declared by both cli tag and InputField.CLI")
		}
		field.cli.Encoding = supplement.CLI.Encoding
	}
	if supplement.CLI.Hidden {
		if field.cli.Hidden {
			return fmt.Errorf("CLI.Hidden is declared twice")
		}
		field.cli.Hidden = true
	}
	if supplement.CLI.Deprecated != "" {
		if field.cli.Deprecated != "" {
			return fmt.Errorf("CLI.Deprecated is declared twice")

View on GitHub (pinned to 7fd6ef3c07)