{"record":{"id":"db85133d0a6f9662","repo":"paperclipai/paperclip","slug":"endindex-must-be-greater-than-startindex","errorCode":null,"errorMessage":"endIndex must be greater than startIndex.","messagePattern":"endIndex must be greater than startIndex\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/google-sheets-mcp-server/src/tools.ts","lineNumber":242,"sourceCode":"      \"clear_values\",\n      \"Clear values in an allowlisted spreadsheet range.\",\n      \"destructive\",\n      readValuesSchema,\n      async ({ spreadsheetId, range }) => {\n        assertAllowed(allowedSpreadsheetIdSet, spreadsheetId);\n        return options.client.clearValues(spreadsheetId, range);\n      },\n    ),\n    makeTool(\n      options,\n      \"delete_rows\",\n      \"Delete rows from an allowlisted spreadsheet tab.\",\n      \"destructive\",\n      deleteRowsSchema,\n      async (input) => {\n        assertAllowed(allowedSpreadsheetIdSet, input.spreadsheetId);\n        if (input.endIndex <= input.startIndex) {\n          throw new Error(\"endIndex must be greater than startIndex.\");\n        }\n        return options.client.deleteRows(input);\n      },\n    ),\n  ];\n}\n","sourceCodeStart":224,"sourceCodeEnd":249,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/packages/google-sheets-mcp-server/src/tools.ts#L224-L249","documentation":"The delete_rows tool validates its inputs against the deleteRowsSchema and additionally enforces the invariant endIndex > startIndex before delegating to client.deleteRows. This guards the Google Sheets batchClear/deleteDimension metadata API from a no-op or inverted range.","triggerScenarios":"A tools/call to delete_rows with endIndex <= startIndex — either equal (zero-width range) or reversed (endIndex less than startIndex). Most often a 0-based vs 1-based indexing mistake or an off-by-one when computing the last row.","commonSituations":"Caller uses inclusive end where the API expects exclusive end; agent computes endIndex from a row count and forgets to add the offset; swapped argument order.","solutions":["Re-check that endIndex is strictly greater than startIndex using the API's 0-based exclusive-end convention.","Swap the two values if they were passed in the wrong order.","Add a client-side assert before invoking the tool."],"exampleFix":"// before\n{ spreadsheetId, tabId, startIndex: 10, endIndex: 10 }  // -> error\n// after\n{ spreadsheetId, tabId, startIndex: 10, endIndex: 11 }","handlingStrategy":"validation","validationCode":"function validRowRange(startIndex: number, endIndex: number): boolean {\n  return Number.isInteger(startIndex) && Number.isInteger(endIndex) && endIndex > startIndex;\n}\nif (!validRowRange(input.startIndex, input.endIndex)) throw new Error('startIndex must be a non-negative integer less than endIndex');","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat endIndex as exclusive and 0-based, matching the underlying Google Sheets dimension range.","Add an assertion in your caller right before invoking delete_rows.","When computing endIndex from a count, remember to offset by startIndex."],"tags":["input-validation","google-sheets-mcp","off-by-one","destructive"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}