hi @AmineAouragh
That line is probably just where the deployed agent failure is being surfaced, not the actual cause.
client.runs.wait(...) in the LangGraph SDK can fail in two different ways that are easy to confuse:
- The HTTP request to Fleet/LangSmith itself returns an HTTP error, for example a real
429 Too Many Requests.
- The request succeeds, the agent run executes on the server, but the run finishes with
__error__; by default runs.wait re-throws that run-level error.
The second case is very likely here. In the SDK source, runs.wait checks the returned run values and, if raiseError is enabled, throws:
`${run.__error__?.error}: ${run.__error__?.message}`
So if the run object contains:
{
"__error__": {
"error": "RateLimitError",
"message": "An internal error occurred at async handler"
}
}
then your caller sees:
RateLimitError: An internal error occurred at async handler
That usually means the model/tool call inside the Fleet agent hit a provider-side rate limit or transient provider/gateway error. It can start happening even if you did not change your code: provider quota, credits, rate-limit tier, API key state, traffic volume, or provider availability can change independently.
The first thing I would do is confirm which case you are in:
try {
const result = await client.runs.wait(null, agentId, {
input: {
messages: [{ role: "user", content: userMessage }],
},
});
return result;
} catch (e: any) {
console.error("Fleet run failed", {
name: e?.name,
message: e?.message,
status: e?.status ?? e?.statusCode,
headers: e?.headers,
cause: e?.cause,
});
throw e;
}
If you see an actual status / statusCode of 429, then you are hitting a platform/API rate-limit path and should back off, reduce request concurrency, and check LangSmith/Fleet rate limits.
If there is no HTTP 429 and the message is just RateLimitError: ..., open the failed run trace in LangSmith and inspect the failing model/child span. That trace should tell you which provider/model failed and whether it was quota, credits, key state, provider overload, or another provider-side issue.
Fixes to try:
- Verify the model provider key used by the Fleet deployment is still valid, funded, and attached to the expected provider org/project.
- Check provider quota/rate-limit dashboards and status page.
- If you control/export the agent code, add resilience there and redeploy: model retries (
max_retries, .with_retry() / .withRetry()), a rate limiter such as InMemoryRateLimiter, or model/tool call caps such as modelCallLimitMiddleware / toolCallLimitMiddleware.
- If you want to inspect run-level failures without
runs.wait throwing, call it with raiseError: false and check result.__error__ yourself:
const result = await client.runs.wait(null, agentId, {
input: {
messages: [{ role: "user", content: userMessage }],
},
raiseError: false,
});
if ((result as any)?.__error__) {
console.log((result as any).__error__);
}
Important caveat: raiseError: false only helps for run-level __error__ responses. It will not prevent an actual HTTP 429 from the API/platform from throwing.
Two React-specific things worth checking:
- If you are calling Fleet directly from browser React with a LangSmith PAT/API key, move that call behind a backend/API route. Otherwise the token is exposed to users, and you cannot centrally throttle/retry.
- Check for duplicate calls from React Strict Mode, repeated effects, re-renders, multiple tabs, or frontend retries. Those can silently double or multiply traffic and trigger rate limits.
Docs: