{"record":{"id":"aaac2a56f3566735","repo":"ruvnet/ruflo","slug":"provider-provider-id-is-rate-limited","errorCode":null,"errorMessage":"Provider ${provider.id} is rate limited","messagePattern":"Provider (.+?) is rate limited","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"v3/@claude-flow/integration/src/provider-adapter.ts","lineNumber":926,"sourceCode":"  }\n\n  /**\n   * Check rate limits before request\n   */\n  private checkRateLimits(provider: Provider): void {\n    // Reset rate limits if needed\n    const now = Date.now();\n    if (now >= provider.rateLimits.resetAt) {\n      provider.rateLimits.currentRequests = 0;\n      provider.rateLimits.currentTokens = 0;\n      provider.rateLimits.resetAt = now + 60000;\n      if (provider.status === 'rate-limited') {\n        provider.status = 'available';\n      }\n    }\n\n    if (provider.status === 'rate-limited') {\n      throw new Error(`Provider ${provider.id} is rate limited`);\n    }\n  }\n\n  /**\n   * Check cost limits\n   */\n  private checkCostLimits(): void {\n    const now = Date.now();\n\n    // Reset hourly cost if needed\n    if (now >= this.hourlyCost.resetAt) {\n      this.hourlyCost.amount = 0;\n      this.hourlyCost.resetAt = now + 3600000;\n    }\n\n    if (this.hourlyCost.amount >= this.config.costLimitPerHour!) {\n      throw new Error(\n        `Hourly cost limit exceeded: $${this.hourlyCost.amount.toFixed(2)} / $${this.config.costLimitPerHour}`","sourceCodeStart":908,"sourceCodeEnd":944,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/integration/src/provider-adapter.ts#L908-L944","documentation":"ProviderAdapter's per-provider rate-limit guard throws when a provider's status is 'rate-limited' and the 60-second window (rateLimits.resetAt) has not elapsed. Requests are refused before dispatch to protect the provider instead of being sent upstream to fail.","triggerScenarios":"Executing or routing a task to a provider whose rateLimits counters tripped the 'rate-limited' status earlier in the same window (now < rateLimits.resetAt); the status only flips back to 'available' once the window resets (resetAt = last reset + 60000ms).","commonSituations":"Bursty fan-out (Promise.all over many tasks or workers) exceeding the provider's configured request/token limits; limits configured lower than the account allows; a shared provider saturated by another component of the system.","solutions":["Back off until rateLimits.resetAt (at most 60s into the window) and resubmit","Throttle or queue upstream (rate limiter with jitter) so bursts stay under the provider's configured limits","Raise the provider's configured rateLimits if the account actually permits more throughput","Register or enable additional providers so selection can route around a limited one"],"exampleFix":"// before\nconst results = await Promise.all(tasks.map(t => adapter.execute(t))); // synchronized burst trips the limit\n\n// after\nimport pLimit from 'p-limit';\nconst limit = pLimit(Math.floor(providerLimits.requestsPerMinute / 60)); // ~ steady rate\nconst results = await Promise.all(tasks.map(t => limit(() => adapter.execute(t))));","handlingStrategy":"retry","validationCode":"// Own the pacing: cap in-flight calls per provider under its configured limit\nconst gate = new Semaphore(Math.floor(providerRateLimits.maxRequestsPerMinute / 60));\nconst run = () => gate.with(() => adapter.execute(task));","typeGuard":null,"tryCatchPattern":"try {\n  await adapter.execute(task);\n} catch (e) {\n  if (e instanceof Error && /rate limited/.test(e.message)) {\n    await sleep(msUntilNextMinuteWindow()); // window is 60s per rateLimits.resetAt\n    return adapter.execute(task); // exactly one rebounce, not a tight loop\n  }\n  throw e;\n}","preventionTips":["Drive dispatch through a per-provider rate limiter sized to the configured limits","Add jitter to fan-out so workers don't burst in lockstep","Watch for 'rate-limited' status transitions and pre-emptively reroute to alternate providers"],"tags":["rate-limit","backpressure","provider","throttling"],"backgroundTag":"rate-limit-exceeded","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}