larksuite/cli · error
%s got conflicting values for %q under two spellings (%q and
Error message
%s got conflicting values for %q under two spellings (%q and %q) — keep one
What it means
The sheets batch op dispatcher normalizes key spellings (snake_case vs kebab-case) for sub-op inputs. When the same logical key is claimed under two spellings and the values differ, it refuses to silently pick one and reports a conflict, telling you to keep a single spelling.
Source
Thrown at shortcuts/sheets/batch_op_dispatch.go:422
}
keys := make([]string, 0, len(input))
for k := range input {
keys = append(keys, k)
}
sort.Strings(keys)
aliases := commandFlagAliases[sc]
// canonical tracks which raw key already claimed each logical key, so two
// spellings of the same flag (sheet-id / sheet_id / sheetId) can never both
// survive into the tool body — the flag view resolves hyphen↔underscore
// variants, so a leftover duplicate would be silently shadowed and could
// send the write to the wrong sheet.
canonical := map[string]string{}
claim := func(logical, raw string) error {
if prev, taken := canonical[logical]; taken {
if jsonEqual(input[prev], input[raw]) {
return nil // same value under two spellings: harmless
}
return fmt.Errorf("%s got conflicting values for %q under two spellings (%q and %q) — keep one", sc, strings.ReplaceAll(logical, "-", "_"), prev, raw) //nolint:forbidigo // intermediate error; the batch dispatcher wraps it into a typed operations validation error
}
canonical[logical] = raw
return nil
}
for _, k := range keys {
hv := strings.ReplaceAll(k, "_", "-")
if vocab[hv] {
if err := claim(hv, k); err != nil {
return err
}
// Normalize the surviving spelling to the underscore form the tool
// bodies use, so exactly one key reaches the flag view.
if target := strings.ReplaceAll(hv, "-", "_"); target != k {
if _, taken := input[target]; !taken {
input[target] = input[k]
delete(input, k)
canonical[hv] = target
}View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Remove one of the two spellings from the sub-op input, keeping the value you intend.
- Make the values identical if both spellings were meant to convey the same setting.
- Standardize on snake_case keys in your payload, matching the canonical target naming.
Example fix
// before
{"cell_range": "A1:B2", "cell-range": "C3:D4"}
// after
{"cell_range": "A1:B2"} Defensive patterns
Strategy: validation
Validate before calling
func dedupeSpellings(op map[string]interface{}) error {
norm := map[string]interface{}{}
for k, v := range op {
n := strings.ReplaceAll(strings.ReplaceAll(k, "_", "-"), "-", "_")
if prev, ok := norm[n]; ok && !reflect.DeepEqual(prev, v) {
return fmt.Errorf("conflicting values for %q", n)
}
norm[n] = v
}
return nil
} Prevention
- Emit sub-op keys in snake_case only.
- Never merge payloads from two different naming-convention sources without normalizing keys first.
- Add a payload lint step that rejects duplicate logical keys.
When it happens
Trigger: A batch operation sub-op input JSON contains both spellings of the same logical field, e.g. `cell_range` and `cell-range`, with different values. If the values are identical it passes; only genuinely conflicting values trigger this.
Common situations: Copy-pasting payload examples from older docs that used kebab-case into scripts using snake_case; merging two partial payloads that each set the field once; tool-generated JSON mixing naming conventions.
Related errors
- %s got both %q and %q — keep %q and drop the other
- %s got both %q and %q, which are two names for the same flag
- %s got both %q and "range" — keep "range" and drop %q
- Range needs a maximum column: {range_ref}
- Range needs a maximum row: {range_ref}
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/f52af7a4efd34839.
Report an issue: GitHub.