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
- Provide a non-empty cell range such as 'A1' or 'A1:B2' for the flag.
- If using a sheet qualifier, include the cell range after it, e.g. 'Sheet1!A1:B2'.
- Check shell variables/expansions that feed the flag so they are not empty.
- 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
- Check flag values are non-empty before invoking commands, especially from shell variables.
- A sheet qualifier alone is not a range — always append cell coordinates.
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
- unsupported range form %q (need rectangular A1:B2)
- end %q must be at or after start %q
- invalid cell ref %q
- unsupported range form %q (need rectangular A1:B2)
- end %q must be at or after start %q
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/dfe93496ed875dc1.
Report an issue: GitHub.