larksuite/cli · error

writing rows %d-%d: %w

Error message

writing rows %d-%d: %w

What it means

writeSheetData writes row batches through the set_cell_range tool; this error wraps a failure of one such batch write, including the failing 1-based row span (start+1 to end). It is an intermediate error surfaced as a partial_success message string via tablePutPartial, meaning earlier batches may already have been written when it fires.

Source

Thrown at shortcuts/sheets/lark_sheet_table_io.go:930

	writes := 0
	for start := 0; start < len(matrix); start += rowsPerBatch {
		end := start + rowsPerBatch
		if end > len(matrix) {
			end = len(matrix)
		}
		batchRange := fmt.Sprintf("%s%d:%s%d", startCol, baseRow+start+1, endCol, baseRow+end)
		input := map[string]interface{}{
			"excel_id": token,
			"sheet_id": sheetID,
			"range":    batchRange,
			"cells":    matrix[start:end],
		}
		if !allowOverwrite {
			input["allow_overwrite"] = false
		}
		if _, err := callTool(ctx, runtime, token, ToolKindWrite, "set_cell_range", input); err != nil {
			return nil, fmt.Errorf("writing rows %d-%d: %w", start+1, end, err) //nolint:forbidigo // intermediate error; surfaced as a partial_success message string via tablePutPartial, not a typed final error
		}
		writes++
	}
	if err := applyWorkbookCreateVisualOps(ctx, runtime, token, sheetID, styles); err != nil {
		return nil, fmt.Errorf("applying visual styles: %w", err) //nolint:forbidigo // intermediate error; surfaced as a partial_success message string via tablePutPartial, not a typed final error
	}
	return map[string]interface{}{
		"name":      s.Name,
		"sheet_id":  sheetID,
		"range":     fmt.Sprintf("%s%d:%s%d", startCol, baseRow+1, endCol, baseRow+len(matrix)),
		"data_rows": len(s.Rows),
		"columns":   writeCols,
		"writes":    writes,
		"mode":      writeModeName(s),
	}, nil
}

// writeModeName normalizes the sheet's write mode to a non-empty label for

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Read the partial_success message for the exact row span that failed, then re-run the put for the remaining data.
  2. If overwrite of existing data is intended, use overwrite mode or allow overwrite so the backend accepts the write.
  3. Retry after a short backoff if the cause is rate limiting (429/ TooManyRequests).
  4. Shrink the payload or ensure the sheet grid is large enough for the row range.

Example fix

// before: append colliding with existing data
lark sheet table put --token T --sheet Data --mode append --row 1,2
// after: switch to overwrite of the intended anchor or clean the target rows first
lark sheet table put --token T --sheet Data --mode overwrite --row 1,2
Defensive patterns

Strategy: validation

Validate before calling

// ensure the target grid can accept the rows before writing:
if mode == "append" && !allowOverwrite {
	// confirm the rows below the current last data row are empty via table get
}

Try / catch

if strings.Contains(err.Error(), "writing rows") {
	// parse the reported row span from the partial_success message and resume from there
}

Prevention

When it happens

Trigger: Calling lark sheet table put when a set_cell_range call fails mid-write: allow_overwrite=false and the target range collides with existing non-empty data, grid too small, or an API-level rejection (permission, rate limit, invalid range).

Common situations: Appending/overwriting into a range that already contains data with allow_overwrite disabled; concurrent editors changing the sheet; sheet grid smaller than the payload; hitting API QPS limits on large payloads.

Related errors


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