larksuite/cli · error
cli token %q is duplicated
Error message
cli token %q is duplicated
What it means
parseCLITag validates the semicolon-delimited `cli:"..."` struct tag grammar for typed input fields. Each token (key=value) may appear at most once; this error fires when the same key is repeated, e.g. two `encoding=` tokens. It is a build-time declaration error caught when the command set is compiled/registered, so a bad tag fails fast instead of silently ignoring the second value.
Source
Thrown at shortcuts/common/typed_compile_args.go:527
if result.minItems != nil && result.maxItems != nil && *result.minItems > *result.maxItems {
return result, fmt.Errorf("minItems exceeds maxItems")
}
return result, nil
}
func parseCLITag(raw string) (typedCLIInput, error) {
var result typedCLIInput
if raw == "" {
return result, nil
}
seen := make(map[string]struct{})
for _, token := range strings.Split(raw, ";") {
key, value, ok := strings.Cut(token, "=")
if !ok || value == "" || token != strings.TrimSpace(token) {
return result, fmt.Errorf("invalid cli token %q", token)
}
if _, duplicate := seen[key]; duplicate {
return result, fmt.Errorf("cli token %q is duplicated", key)
}
seen[key] = struct{}{}
switch key {
case "sources":
for _, source := range strings.Split(value, "|") {
result.ValueSources = append(result.ValueSources, typedValueSource(source))
}
case "encoding":
result.Encoding = typedCLIEncoding(value)
default:
return result, fmt.Errorf("unknown cli token %q", key)
}
}
return result, nil
}
func parseFiniteFloat(value string) (float64, error) {
return parseFiniteFloatBits(value, 64)View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Remove the duplicated token so each key appears at most once in the cli tag
- If you intended multiple sources, use the pipe separator within a single sources token, e.g. sources=a|b
- Run the command's compile/startup test (or `go test` on the shortcut package) to confirm the tag parses
Example fix
// before Field string `cli:"encoding=json;encoding=text"` // after Field string `cli:"encoding=json"`
Defensive patterns
Strategy: validation
Validate before calling
func validateCLITagKeys(raw string) error {
seen := map[string]bool{}
for _, tok := range strings.Split(raw, ";") {
key, _, ok := strings.Cut(tok, "=")
if !ok || key == "" { return fmt.Errorf("bad token %q", tok) }
if seen[key] { return fmt.Errorf("duplicate cli key %q", key) }
seen[key] = true
}
return nil
} Prevention
- Keep each cli tag to unique keys; never duplicate encoding/sources tokens
- Combine multiple sources in one token with the | separator
- Add a unit test parsing every declared struct tag in the package
When it happens
Trigger: Declaring a struct field whose `cli` tag repeats a key, e.g. `cli:"sources=a|b;encoding=json;encoding=text"`. parseCLITag splits on ';', cuts on '=', and rejects any key already present in the seen-set.
Common situations: Copy-pasting a cli tag and forgetting to remove a token; merging two field definitions or rebasing branches where both sides added a token; hand-editing generated or documented tag examples.
Related errors
- Args field %s (--%s): json tag is not allowed on a CLI field
- unknown cli token %q
- invalid cli token %q
- Invalid column: {column!r}
- Invalid column index: {index}
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/0186776764ff7898.
Report an issue: GitHub.