larksuite/cli · error

invalid cell ref %q

Error message

invalid cell ref %q

What it means

When parseCellRange receives a single-token range (no colon), it treats it as one cell and validates it with splitCellRef. If the token is not a valid cell reference (column letters followed by a row number, e.g. 'A1'), it throws 'invalid cell ref'. It is an intermediate error later wrapped into a typed --range/--source-range validation error.

Source

Thrown at shortcuts/sheets/lark_sheet_write_cells.go:1149

	out := cellRange{}
	// Trim before cutting the qualifier, not after: otherwise " sheet1!B2"
	// carries the leading space into it and into every range rendered from it.
	body := strings.TrimSpace(s)
	if _, end, ok := scanSheetQualifier(body); ok {
		out.sheetQualifier = body[:end]
		body = strings.TrimSpace(body[end:])
	}
	if body == "" {
		return out, fmt.Errorf("empty range") //nolint:forbidigo // intermediate error; callers wrap it into a typed --range/--source-range validation error
	}
	parts := strings.SplitN(body, ":", 2)
	out.start = strings.TrimSpace(parts[0])
	startCol, startRow, ok := splitCellRef(out.start)
	out.col, out.row = startCol, startRow
	if len(parts) == 1 {
		// single cell, e.g. "A1"
		if !ok {
			return cellRange{}, fmt.Errorf("invalid cell ref %q", parts[0]) //nolint:forbidigo // intermediate error; callers wrap it into a typed --range/--source-range validation error
		}
		out.rows, out.cols, out.anchored = 1, 1, true
		return out, nil
	}
	endCol, endRow, okEnd := splitCellRef(parts[1])
	if !ok || !okEnd {
		return cellRange{}, fmt.Errorf("unsupported range form %q (need rectangular A1:B2)", body) //nolint:forbidigo // intermediate error; callers wrap it into a typed --range/--source-range validation error
	}
	if endRow < startRow || endCol < startCol {
		return cellRange{}, fmt.Errorf("end %q must be at or after start %q", parts[1], parts[0]) //nolint:forbidigo // intermediate error; callers wrap it into a typed --range/--source-range validation error
	}
	out.rows, out.cols = endRow-startRow+1, endCol-startCol+1
	return out, nil
}

func rangeDimensions(rangeStr string) (rows, cols int, err error) {
	r, err := parseCellRange(rangeStr)
	if err != nil {

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Use a valid cell reference of the form ColumnLetters+RowNumber, e.g. 'A1'.
  2. If a range was intended, supply the full 'A1:B2' form.
  3. Ensure the row number is >= 1; 'A0' is invalid.
  4. Check --help/schema for accepted single-cell and range formats.

Example fix

// before
--range "A0"
--range "A"
// after
--range "A1"
Defensive patterns

Strategy: validation

Validate before calling

var cellRe = regexp.MustCompile(`^[A-Za-z]+[1-9][0-9]*$`)
if !cellRe.MatchString(single) {
	return fmt.Errorf("%q is not a cell ref like A1", single)
}

Type guard

func isCellRef(s string) bool {
	i := 0
	for i < len(s) && isLetter(s[i]) { i++ }
	if i == 0 || i == len(s) { return false }
	for ; i < len(s); i++ { if !isDigit(s[i]) { return false } }
	return s[len(s)-1] != '0' || rowNumber(s) > 0
}

Prevention

When it happens

Trigger: Passing a single value without a colon that is not a cell reference, e.g. 'A', '1', 'AA0' (row 0 invalid), '1A', or a whole-column spec like 'A:C' mis-split by other logic.

Common situations: Users intending a whole row/column ('A' or '1'), typos in the cell reference, row number 0, or lowercase/odd formats not accepted by the parser.

Related errors


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