larksuite/cli · error

empty range

Error message

empty range

What it means

parseCellRange parses --range/--source-range strings into a cellRange. After stripping an optional 'Sheet!' qualifier, if nothing remains to parse it reports 'empty range'. This is an intermediate error that callers wrap into a typed --range/--source-range validation error.

Source

Thrown at shortcuts/sheets/lark_sheet_write_cells.go:1140

// get_sheet_structure, outside the scope of pure local parsing. The error
// wording is load-bearing: +styles-put surfaces it verbatim
// ("cell_styles range %q: %v").
//
// The sheet part is cut by scanSheetQualifier, the same grammar the selector
// rewrite uses, so both agree with the front-end ref lexer on what counts as a
// separator. Splitting on the first "!" instead would miss the full-width
// separator entirely and would cut a quoted name in half at its own "!".
func parseCellRange(s string) (cellRange, error) {
	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 {

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Provide a non-empty cell range such as 'A1' or 'A1:B2' for the flag.
  2. If using a sheet qualifier, include the cell range after it, e.g. 'Sheet1!A1:B2'.
  3. Check shell variables/expansions that feed the flag so they are not empty.
  4. Consult --help/schema for the expected --range/--source-range format.

Example fix

// before
--range ""
--range "Sheet1!"
// after
--range "Sheet1!A1:B2"
Defensive patterns

Strategy: validation

Validate before calling

r := strings.TrimSpace(rangeFlag)
if r == "" || strings.HasSuffix(r, "!") {
	return fmt.Errorf("--range must include a cell range, e.g. Sheet1!A1:B2")
}

Type guard

func nonEmptyRange(s string) bool { return strings.TrimSpace(strings.TrimSuffix(strings.TrimSpace(s), "!")) != "" }

Prevention

When it happens

Trigger: Passing an empty string, only whitespace, or a value consisting solely of a sheet qualifier like 'Sheet1!' (nothing after the '!') to a flag parsed by parseCellRange (used by checkCellsMatchRange, expandAnchorRange, rangeDimensions).

Common situations: Shell variable expansion producing an empty value (unset env var), users typing only the sheet name with trailing '!', or copy-pasting a range that got trimmed away.

Related errors


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