Google Sheets — Verify After Write
Claude Code is multimodal — it can see screenshots via the Read tool. Use this
to close a visual feedback loop after every Google Sheets write operation.
Verify-After-Write Workflow
Applies to ALL Google Sheets write operations: update values, sort, insert/delete
rows, format, borders, batchUpdate.
Steps
- Execute the Sheets API command (update, batchUpdate, sort, etc.)
- Open the sheet in Playwright:
browser_navigate to the spreadsheet URL
Use the specific tab URL if working on a named tab (append #gid=SHEET_ID).
- Wait for render:
browser_wait_for selector=".grid-container" or timeout 5000
- Take screenshot:
browser_take_screenshot (full page or element-specific)
- Read the screenshot with the
Read tool to visually inspect.
- Apply the Self-Review Checklist (below).
- If issues found: fix the command, re-execute, re-verify (max 2 cycles).
- If still broken after 3 cycles, report to user with the screenshot.
Important Notes
- Maximum 3 total verify cycles (initial + 2 fixes)
- The Playwright browser must be authenticated with Google (session cookies)
- For automated skills (cron), screenshot verification may not be possible —
use API read-back as fallback
Self-Review Checklist
After reading the screenshot, check:
Data Integrity
- All columns are still aligned — no column was sorted independently
- Row count matches expected (check against pre-write count)
- No blank rows inserted where data should be
- Cell values match what was written (spot-check a few cells)
Sort Order
- Rows sorted by the correct field
- All columns within each row moved together (no detached columns)
- Never sort a single column — always sort entire rows
Borders and Formatting
- All data rows have visible horizontal divider lines (top/bottom borders)
- Vertical dividers present between columns where expected
- The last data row has correct borders (bulk ops often miss it)
- No broken/missing borders anywhere in the data range
- Number format preserved (currency, percentages, dates)
Layout
- Headers are intact and not shifted
- Frozen rows/columns still in place
- Column widths haven't collapsed
- No overflow text hiding adjacent cell content
Hard Rules for Google Sheets Operations
Sorting
- Sort entire rows, NEVER individual columns — a sort that moves only one column
detaches it from the rest of the row, corrupting every record
Borders
- Use
copyPaste PASTE_FORMAT to apply borders — NEVER updateBorders.
updateBorders only sets top/bottom/innerHorizontal for the range; it does NOT
set per-column left/right entries, resulting in missing vertical dividers
- Use generous
endRowIndex buffer (+10 or 200) for bulk format operations —
a fixed endRowIndex silently misses the last row when rows are added
- After
insertDimension at index N, copy format from row N+1 (pushed down) to
the new row at N
- Always verify the last data row has correct borders after any bulk operation
API Read-Back Fallback
When Playwright is unavailable (e.g., cron automation), verify via API:
# Read back the data range after writing
gws sheets spreadsheets.values get \
--spreadsheetId SHEET_ID \
--range "TAB_NAME!A1:G100" \
--json values
Check that:
- Row count matches expected
- Column alignment is intact (each row has the same number of values)
- Sort order is correct (compare key fields across rows)
This catches data issues but NOT formatting. Flag formatting as "unverified"
when using API-only fallback.
Requirements
- Claude Code with multimodal
Read tool
- Playwright MCP server for screenshots
- Google Sheets API access (via
gws CLI, Google Apps Script, or direct API)
- Playwright browser authenticated with Google (for screenshot access)
1---2name: gws-sheets-verify3description: Visual feedback loop for Google Sheets operations. After any write, take a Playwright screenshot and verify data integrity, sort order, and formatting.4---56# Google Sheets — Verify After Write78Claude Code is multimodal — it can see screenshots via the `Read` tool. Use this9to close a visual feedback loop after every Google Sheets write operation.1011---1213## Verify-After-Write Workflow1415**Applies to ALL Google Sheets write operations:** update values, sort, insert/delete16rows, format, borders, batchUpdate.1718### Steps19201. **Execute** the Sheets API command (update, batchUpdate, sort, etc.)212. **Open the sheet** in Playwright:22 ```23 browser_navigate to the spreadsheet URL24 ```25 Use the specific tab URL if working on a named tab (append `#gid=SHEET_ID`).263. **Wait for render:**27 ```28 browser_wait_for selector=".grid-container" or timeout 500029 ```304. **Take screenshot:**31 ```32 browser_take_screenshot (full page or element-specific)33 ```345. **Read the screenshot** with the `Read` tool to visually inspect.356. **Apply the Self-Review Checklist** (below).367. **If issues found:** fix the command, re-execute, re-verify (max 2 cycles).378. If still broken after 3 cycles, report to user with the screenshot.3839### Important Notes4041- Maximum 3 total verify cycles (initial + 2 fixes)42- The Playwright browser must be authenticated with Google (session cookies)43- For automated skills (cron), screenshot verification may not be possible —44 use API read-back as fallback4546---4748## Self-Review Checklist4950After reading the screenshot, check:5152### Data Integrity5354- All columns are still aligned — no column was sorted independently55- Row count matches expected (check against pre-write count)56- No blank rows inserted where data should be57- Cell values match what was written (spot-check a few cells)5859### Sort Order6061- Rows sorted by the correct field62- All columns within each row moved together (no detached columns)63- **Never sort a single column** — always sort entire rows6465### Borders and Formatting6667- All data rows have visible horizontal divider lines (top/bottom borders)68- Vertical dividers present between columns where expected69- The **last data row** has correct borders (bulk ops often miss it)70- No broken/missing borders anywhere in the data range71- Number format preserved (currency, percentages, dates)7273### Layout7475- Headers are intact and not shifted76- Frozen rows/columns still in place77- Column widths haven't collapsed78- No overflow text hiding adjacent cell content7980---8182## Hard Rules for Google Sheets Operations8384### Sorting85- **Sort entire rows, NEVER individual columns** — a sort that moves only one column86 detaches it from the rest of the row, corrupting every record8788### Borders89- **Use `copyPaste PASTE_FORMAT`** to apply borders — NEVER `updateBorders`.90 `updateBorders` only sets top/bottom/innerHorizontal for the range; it does NOT91 set per-column `left`/`right` entries, resulting in missing vertical dividers92- **Use generous `endRowIndex` buffer** (+10 or 200) for bulk format operations —93 a fixed `endRowIndex` silently misses the last row when rows are added94- After `insertDimension` at index N, copy format from row N+1 (pushed down) to95 the new row at N96- **Always verify the last data row** has correct borders after any bulk operation9798---99100## API Read-Back Fallback101102When Playwright is unavailable (e.g., cron automation), verify via API:103104```bash105# Read back the data range after writing106gws sheets spreadsheets.values get \107 --spreadsheetId SHEET_ID \108 --range "TAB_NAME!A1:G100" \109 --json values110```111112Check that:113- Row count matches expected114- Column alignment is intact (each row has the same number of values)115- Sort order is correct (compare key fields across rows)116117This catches data issues but NOT formatting. Flag formatting as "unverified"118when using API-only fallback.119120---121122## Requirements123124- [Claude Code](https://claude.ai/code) with multimodal `Read` tool125- [Playwright MCP server](https://github.com/anthropics/claude-code/tree/main/plugins/playwright) for screenshots126- Google Sheets API access (via `gws` CLI, Google Apps Script, or direct API)127- Playwright browser authenticated with Google (for screenshot access)