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

  1. Remove one of the two spellings from the sub-op input, keeping the value you intend.
  2. Make the values identical if both spellings were meant to convey the same setting.
  3. 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

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


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