ruvnet/ruflo · error · RateLimitError
RATE_LIMIT
RATE_LIMIT
Error message
${message} What it means
CohereProvider maps HTTP 429 to RateLimitError (retryable). Cohere returns 429 when you exceed organization rate limits (requests or tokens per minute) or trial-tier caps. Note that this mapping passes retryAfter as undefined - the library does not extract Cohere's retry-after header here, so callers must apply their own backoff.
Source
Thrown at v3/@claude-flow/providers/src/cohere-provider.ts:411
}
private async handleErrorResponse(response: Response): Promise<never> {
const errorText = await response.text();
let errorData: { message?: string };
try {
errorData = JSON.parse(errorText);
} catch {
errorData = { message: errorText };
}
const message = errorData.message || 'Unknown error';
switch (response.status) {
case 401:
throw new AuthenticationError(message, 'cohere', errorData);
case 429:
throw new RateLimitError(message, 'cohere', undefined, errorData);
default:
throw new LLMProviderError(
message,
`COHERE_${response.status}`,
'cohere',
response.status,
response.status >= 500,
errorData
);
}
}
}
View on GitHub (pinned to fa13ee4ad6)
Solutions
- Retry on RateLimitError with exponential backoff and jitter (start ~1 s, double, cap ~60 s)
- Reduce concurrency (e.g. p-limit) and batch size to stay under RPM/TPM
- Inspect the Cohere dashboard for current limits and upgrade the plan if throttling is sustained
- Read error.details for Cohere's response body and honor any retry-after information it carries
Example fix
// before
const res = await provider.complete(req); // 429 propagates as RateLimitError
// after - retry with backoff on RateLimitError
async function completeWithBackoff(provider, req, tries = 5) {
for (let i = 0; ; i++) {
try { return await provider.complete(req); }
catch (e) {
if (e instanceof RateLimitError && i < tries - 1) {
await new Promise(r => setTimeout(r, Math.min(60_000, 2 ** i * 1000)));
continue;
}
throw e;
}
}
} Defensive patterns
Strategy: retry
Type guard
import { RateLimitError } from './types.js';
function isCohereRateLimit(e: unknown): e is RateLimitError {
return e instanceof RateLimitError && e.provider === 'cohere';
} Try / catch
for (let attempt = 0; ; attempt++) {
try {
return await provider.complete(req);
} catch (e) {
if (isCohereRateLimit(e) && attempt < 5) {
// this mapping leaves retryAfter undefined - choose your own backoff
await new Promise(r => setTimeout(r, Math.min(60_000, 2 ** attempt * 1000) + Math.random() * 500));
continue;
}
throw e;
}
} Prevention
- Cap concurrency below your Cohere RPM/TPM with p-limit or a queue
- Add jittered exponential backoff for 429s rather than immediate retries
- Track 429 rate per provider in metrics and alert before it becomes an outage
When it happens
Trigger: A burst of provider.complete() calls exceeding the plan's RPM/TPM; many parallel completions from a fan-out workflow; load testing against a trial key.
Common situations: Concurrent batch generation without a concurrency limit; production traffic spike; plan too small for sustained throughput.
Related errors
- RATE_LIMIT
- RATE_LIMIT
- Amendment rate limit exceeded: ${this.maxAmendmentsPerWindow
- Provider ${provider.id} is rate limited
- MCP server "${server.name}" is in cooldown (HTTP ${cd.status
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/8908ad866440431f.
Report an issue: GitHub.