larksuite/cli · error

empty range

Error message

empty range

What it means

workbookCreateStyleRangeBounds parses a style/merge range string like 'Sheet1!A1:C3' into column/row bounds. This error is returned when the range portion is empty after stripping any 'Sheet!' prefix and trimming whitespace. It is an intermediate error; callers (parseWorkbookCreateCellStyleOp, parseWorkbookCreateMergeOp) wrap it into a typed validation error with flag/param context.

Source

Thrown at shortcuts/sheets/lark_sheet_workbook.go:2108

		if op.FreezeRows > 0 {
			input["freeze_rows"] = op.FreezeRows
		}
		if op.FreezeCols > 0 {
			input["freeze_columns"] = op.FreezeCols
		}
		return input, "modify_sheet_structure"
	default:
		return nil, ""
	}
}

func workbookCreateStyleRangeBounds(rangeStr string) (startCol, startRow, endCol, endRow int, err error) {
	if idx := strings.Index(rangeStr, "!"); idx >= 0 {
		rangeStr = rangeStr[idx+1:]
	}
	rangeStr = strings.TrimSpace(rangeStr)
	if rangeStr == "" {
		return 0, 0, 0, 0, fmt.Errorf("empty range") //nolint:forbidigo // intermediate error; callers wrap it into a typed validation error with flag/param context
	}
	parts := strings.SplitN(rangeStr, ":", 2)
	if len(parts) == 1 {
		col, row, ok := splitCellRef(parts[0])
		if !ok {
			return 0, 0, 0, 0, fmt.Errorf("invalid cell ref %q", parts[0]) //nolint:forbidigo // intermediate error; callers wrap it into a typed validation error with flag/param context
		}
		return col, row, col, row, nil
	}
	startCol, startRow, ok1 := splitCellRef(parts[0])
	endCol, endRow, ok2 := splitCellRef(parts[1])
	if !ok1 || !ok2 {
		return 0, 0, 0, 0, fmt.Errorf("unsupported range form %q (need rectangular A1:B2)", rangeStr) //nolint:forbidigo // intermediate error; callers wrap it into a typed validation error with flag/param context
	}
	if endRow < startRow || endCol < startCol {
		return 0, 0, 0, 0, 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 validation error with flag/param context
	}
	return startCol, startRow, endCol, endRow, nil

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Provide a concrete range like 'A1:C3' (optionally with a 'SheetName!' prefix) in the style/merge entry.
  2. Remove the empty range entry if the style op was added unintentionally.
  3. Check the typed validation error's flag/param context to find which styles entry is empty.
  4. Validate ranges in your payload generator before calling the put.

Example fix

// before
{"styles": [{"range": "", "bg": "#EEE"}]}
// after
{"styles": [{"range": "A1:C3", "bg": "#EEE"}]}
Defensive patterns

Strategy: validation

Validate before calling

func hasRange(r string) bool {
	if i := strings.Index(r, "!"); i >= 0 { r = r[i+1:] }
	return strings.TrimSpace(r) != ""
}
// before the put:
for _, st := range styles { if !hasRange(st.Range) { return fmt.Errorf("empty range in %v", st) } }

Prevention

When it happens

Trigger: lark sheet table put with a styles or merge entry whose 'range' field is an empty string or only a sheet prefix like 'Sheet1!' with nothing after the '!'.

Common situations: Hand-written style JSON where the range key was left empty; template-driven payloads where a variable that should hold the range expanded to nothing.

Related errors


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