larksuite/cli · error

duplicate value source %q

Error message

duplicate value source %q

What it means

ValueSources must be unique per input field; validateInputCLI tracks sources in a seenSources set and rejects any source appearing twice. Duplicates are meaningless (a source either contributes a value or not) and usually indicate a copy/paste or merge mistake.

Source

Thrown at shortcuts/common/typed_compile_args.go:287

func validateInputCLI(field *compiledInputField) error {
	if field.cli.Deprecated != "" && !field.cli.Hidden {
		return fmt.Errorf("deprecated primary flag must be hidden")
	}
	if field.required && field.defaultValue.Set {
		return fmt.Errorf("required input cannot declare a default")
	}
	if field.defaultValue.Set {
		if err := valueAssignableTo(field.defaultValue.Value, field.valueType); err != nil {
			return fmt.Errorf("default: %w", err)
		}
	}
	seenSources := make(map[typedValueSource]struct{})
	for _, source := range field.cli.ValueSources {
		if source != typedSourceFlag && source != typedSourceFile && source != typedSourceStdin {
			return fmt.Errorf("unknown value source %q", source)
		}
		if _, duplicate := seenSources[source]; duplicate {
			return fmt.Errorf("duplicate value source %q", source)
		}
		seenSources[source] = struct{}{}
	}
	if len(field.cli.ValueSources) > 0 {
		if _, ok := seenSources[typedSourceFlag]; !ok {
			return fmt.Errorf("ValueSources must include flag")
		}
		if (len(seenSources) > 1) && indirectKind(field.valueType) != reflect.String && field.cli.Encoding != typedEncodingJSON {
			return fmt.Errorf("file/stdin sources require string input or encoding=json")
		}
	}
	kind := indirectKind(field.valueType)
	if kind == reflect.Slice || kind == reflect.Array || kind == reflect.Struct || kind == reflect.Map || kind == reflect.Interface {
		if field.cli.Encoding == "" {
			return fmt.Errorf("%s input must explicitly declare CLI encoding", kind)
		}
	}
	switch field.cli.Encoding {

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Deduplicate the ValueSources list, keeping each of flag/file/stdin at most once
  2. Review where the tag is constructed to remove the duplication (e.g. use a set before building the slice)
  3. Remove the extra entry if it was added by mistake

Example fix

// before
ValueSources: []string{"flag", "file", "file"}
// after
ValueSources: []string{"flag", "file"}
Defensive patterns

Strategy: validation

Validate before calling

func dedupe(srcs []string) []string {
	seen := map[string]bool{}
	out := srcs[:0]
	for _, s := range srcs {
		if !seen[s] {
			seen[s] = true
			out = append(out, s)
		}
	}
	return out
}

Try / catch

if err := compileInput(...); err != nil {
	if strings.Contains(err.Error(), "duplicate value source") {
		// deduplicate ValueSources and recompile
	}
	return err
}

Prevention

When it happens

Trigger: Listing the same source twice in ValueSources, e.g. [flag, file, file] or [flag, stdin, stdin], via the cli tag or InputField.CLI. Raised by compileInput during shortcut compilation.

Common situations: Appending a source to a list that already contained it; merging two field declarations and concatenating their ValueSources; generating the tag from code with a loop bug.

Related errors


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