alibaba/page-agent · warning · InvokeError
RATE_LIMIT
RATE_LIMIT
Error message
Rate limit exceeded: ${errorMessage} What it means
The endpoint returned HTTP 429 — you've exceeded a rate limit or quota (requests per minute, tokens per minute, or billing cap). The provider's error message and body are attached so you can see which limit was hit.
Source
Thrown at packages/llms/src/OpenAIClient.ts:109
// 3. Handle HTTP errors
if (!response.ok) {
let errorData: any
try {
errorData = await response.json()
} catch (error) {
if ((error as any)?.name === 'AbortError') throw error
}
const errorMessage = errorData?.error?.message || response.statusText
if (response.status === 401 || response.status === 403) {
throw new InvokeError(
InvokeErrorTypes.AUTH_ERROR,
`Authentication failed: ${errorMessage}`,
errorData
)
}
if (response.status === 429) {
throw new InvokeError(
InvokeErrorTypes.RATE_LIMIT,
`Rate limit exceeded: ${errorMessage}`,
errorData
)
}
if (response.status >= 500) {
throw new InvokeError(
InvokeErrorTypes.SERVER_ERROR,
`Server error: ${errorMessage}`,
errorData
)
}
throw new InvokeError(
InvokeErrorTypes.UNKNOWN,
`HTTP ${response.status}: ${errorMessage}`,
errorData
)
}View on GitHub (pinned to d02db1ee7c)
Solutions
- Add exponential backoff retry on RATE_LIMIT errors (respect Retry-After header if present)
- Reduce request frequency or concurrency in the calling loop
- Check the provider dashboard for which limit (RPM/TPM/billing) is hit and request a raise or top up billing
- Switch to a higher-limit model tier or distribute across keys/projects
Example fix
// before
const result = await llm.invoke(request)
// after
async function invokeWithBackoff(llm, request, retries = 3) {
for (let i = 0; i <= retries; i++) {
try { return await llm.invoke(request) }
catch (e) {
if (e.code !== 'RATE_LIMIT' || i === retries) throw e
await new Promise(r => setTimeout(r, 2 ** i * 1000))
}
}
} Defensive patterns
Strategy: retry
Validate before calling
// throttle before invoking: simple token bucket if (now - lastCallTime < minIntervalMs) await sleep(minIntervalMs - (now - lastCallTime)) await client.invoke(req)
Type guard
const isRateLimitError = (e: unknown): e is InvokeError => e instanceof InvokeError && e.code === 'RATE_LIMIT'
Try / catch
for (let attempt = 0; ; attempt++) {
try { return await client.invoke(req) }
catch (e) {
if (!isRateLimitError(e) || attempt >= 5) throw e
await sleep(2 ** attempt * 500)
}
} Prevention
- Serialize or cap concurrency of agent loops that call invoke()
- Cache identical completions within a session
- Track RPM against your account tier and alert before hitting it
When it happens
Trigger: invoke() bursts requests faster than the account/provider RPM/TPM allows; shared free-tier quota exhausted; concurrent agent loops firing many chat/completions calls; a specific model having a stricter tier limit.
Common situations: Agentic loops with no throttling; free-tier keys (strict RPM); retry storms amplifying traffic; billing quota exhausted; multiple environments sharing one key.
Related errors
AI-assisted analysis of alibaba/page-agent@d02db1ee7c (2026-08-28).
Data as JSON: /api/errors/e1444c252412306c.
Report an issue: GitHub.