{"record":{"id":"f2f481f58ab887bf","repo":"Foundry376/Mailspring","slug":"grammar-check-rate-limit-reached-please-try-again","errorCode":null,"errorMessage":"Grammar check rate limit reached, please try again shortly.","messagePattern":"Grammar check rate limit reached, please try again shortly\\.","errorType":"http","errorClass":null,"httpStatus":429,"severity":"error","filePath":"app/internal_packages/composer-grammar-check/lib/grammar-check-service.ts","lineNumber":139,"sourceCode":"      data = await MailspringAPIRequest.makeRequest({\n        server: 'identity',\n        method: 'POST',\n        path: '/api/grammar/check',\n        json: true,\n        body: {\n          messageId,\n          text,\n          language: language || this.language,\n        },\n      });\n    } catch (err) {\n      // 400 = quota reached (\"Quota Reached\")\n      if (err.statusCode === 400) {\n        throw new UsageExceededError();\n      }\n      // 429 = rate limited — surface as a transient error, caller will retry on next dirty check\n      if (err.statusCode === 429) {\n        throw new Error('Grammar check rate limit reached, please try again shortly.');\n      }\n      // 502 = LanguageTool backend unavailable\n      if (err.statusCode === 502) {\n        throw new Error('Grammar check service is temporarily unavailable.');\n      }\n      throw err;\n    }\n\n    const filtered = data.matches.filter((match) => match.rule.issueType !== 'misspelling');\n\n    return filtered.map((match) => ({\n      offset: match.offset,\n      length: match.length,\n      message: match.message,\n      shortMessage: match.shortMessage || '',\n      replacements: match.replacements.map((r) => r.value),\n      ruleId: match.rule.id,\n      ruleDescription: match.rule.description,","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/Foundry376/Mailspring/blob/648c685d602ece6bb00c22534b8734de6ac644b3/app/internal_packages/composer-grammar-check/lib/grammar-check-service.ts#L121-L157","documentation":"Thrown when the grammar-check endpoint returns HTTP 429: the client is sending checks too fast and is being rate limited. It is deliberately a generic transient error so the caller treats it as non-fatal and simply retries on the next dirty-state check.","triggerScenarios":"Thrown at app/internal_packages/composer-grammar-check/lib/grammar-check-service.ts:139 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["No user action needed: swallow the error and let the next debounce/dirty check retry automatically","Add exponential backoff or increase the check debounce interval to avoid hammering the endpoint"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"648c685d602ece6bb00c22534b8734de6ac644b3","analyzedAt":"2026-09-03T02:00:24.311Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T07:17:11.731Z"}