Mintplex-Labs/anything-llm · warning
Rate limit exceeded
Error message
Rate limit exceeded
What it means
Daily quota enforcement inside canRespond: when the embed has max_chats_per_day > 0 and the count of EmbedChats rows for that embed in the last 24 hours has reached it, the request gets HTTP 429 with a structured abort payload whose error field is 'Rate limit exceeded'. The window is rolling (createdAt >= now-24h), counted across ALL sessions on the embed.
Source
Thrown at server/utils/middleware/embedMiddleware.js:137
? "Message is empty."
: `${embed.chat_mode} is not a valid mode.`,
});
return;
}
if (
!isNaN(embed.max_chats_per_day) &&
Number(embed.max_chats_per_day) > 0
) {
const dailyChatCount = await EmbedChats.count({
embed_id: embed.id,
createdAt: {
gte: new Date(new Date() - 24 * 60 * 60 * 1000),
},
});
if (dailyChatCount >= Number(embed.max_chats_per_day)) {
response.status(429).json({
id: uuidv4(),
type: "abort",
textResponse: null,
sources: [],
close: true,
error: "Rate limit exceeded",
errorMsg:
"The quota for this chat has been reached. Try again later or contact the site owner.",
});
return;
}
}
if (
!isNaN(embed.max_chats_per_session) &&
Number(embed.max_chats_per_session) > 0
) {
const dailySessionCount = await EmbedChats.count({View on GitHub (pinned to 3aec848f28)
Solutions
- Raise or clear max_chats_per_day on the embed config (blank/0 disables the quota), then messages resume immediately
- Wait for chats to fall out of the rolling 24h window — no fixed midnight reset exists
- Widget side: on 429 with type:'abort' and close:true, stop retrying; the window is hours, not seconds
Defensive patterns
Strategy: retry
Validate before calling
// owner-side: keep quota sane so real users don't hit it mid-conversation
if (!Number.isFinite(Number(embed.max_chats_per_day)) || Number(embed.max_chats_per_day) < 1)
console.info('Daily quota disabled for embed', embed.uuid); Try / catch
if (res.status === 429) {
const data = await res.json();
if (data.error === 'Rate limit exceeded') {
showQuotaNotice(data.errorMsg); // visitor-friendly text ships in errorMsg
scheduleRetryAfterRollingWindow(); // 24h rolling window — do NOT tight-loop
}
} Prevention
- Set max_chats_per_day from expected traffic, not a leftover test value
- Treat 429 + type:'abort' + close:true as terminal for the current visit
- Alert admins when an embed's daily denial rate spikes (bot traffic)
When it happens
Trigger: Popular embed hitting its configured daily cap: any message once count >= max_chats_per_day returns 429 until enough old chats age out of the 24h window. Triggered by real traffic, shared scraping of a public embed, or a low cap set during testing.
Common situations: Demo embed left with max_chats_per_day=5 hitting the cap immediately; bot traffic burning the quota; admin forgot the cap was set on production embeds.
Related errors
- The quota for this chat has been reached. Try again later or
- Your quota for this chat has been reached. Try again later o
- res.statusText
- e.message
- LiteLLM Failed to embed: ${error}
AI-assisted analysis of Mintplex-Labs/anything-llm@3aec848f28 (2026-08-18).
Data as JSON: /api/errors/8e40b3742865047f.
Report an issue: GitHub.