langgenius/dify · warning · InvokeRateLimitHttpError
rate_limit_error
rate_limit_error
Error message
Rate Limit Error
What it means
InvokeRateLimitHttpError (HTTP 429, code 'rate_limit_error') is raised in ChatApi.post when AppGenerateService.generate throws services.errors.llm.InvokeRateLimitError. This specifically indicates the model provider returned a rate-limit response (e.g. OpenAI HTTP 429 'Too Many Requests') during a chat-completion call on an installed Explore app. It is caught separately from the generic InvokeError so callers can implement backoff.
Source
Thrown at api/controllers/console/explore/completion.py:235
# response-contract:ignore compact_generate_response
return helper.compact_generate_response(response)
except services.errors.conversation.ConversationNotExistsError:
raise NotFound("Conversation Not Exists.")
except services.errors.conversation.ConversationCompletedError:
raise ConversationCompletedError()
except services.errors.app_model_config.AppModelConfigBrokenError:
logger.exception("App model config broken.")
raise AppUnavailableError()
except ProviderTokenNotInitError as ex:
raise ProviderNotInitializeError(ex.description)
except QuotaExceededError:
raise ProviderQuotaExceededError()
except ModelCurrentlyNotSupportError:
raise ProviderModelCurrentlyNotSupportError()
except InvokeError as e:
raise CompletionRequestError(e.description)
except InvokeRateLimitError as ex:
raise InvokeRateLimitHttpError(ex.description)
except ValueError as e:
raise e
except Exception:
logger.exception("internal server error.")
raise InternalServerError()
@console_ns.route(
"/installed-apps/<uuid:installed_app_id>/chat-messages/<string:task_id>/stop",
endpoint="installed_app_stop_chat_completion",
)
class ChatStopApi(InstalledAppResource):
@console_ns.response(200, "Success", console_ns.models[SimpleResultResponse.__name__])
@with_current_user_id
@with_session(write=False)
def post(self, session: Session, current_user_id: str, installed_app: InstalledApp, task_id: str):
app_model = installed_app.app_with_session(session=session)
if app_model is None:View on GitHub (pinned to ef8544b173)
Solutions
- Implement client-side exponential backoff with jitter and retry after a brief wait (the error is transient by nature).
- Reduce the request rate — add client-side throttling or a queue to stay under the provider's documented RPM/TPM limits.
- Upgrade the provider API plan to a higher rate-limit tier, or configure a dedicated provider key for high-traffic apps.
- Check Settings → Model Provider for the specific provider's rate-limit details and consider spreading load across multiple providers.
Example fix
// before: fire requests in a tight loop
for (const q of queries) { await post('/chat-messages', {query: q}); }
// after: retry with backoff on 429
async function chatWithRetry(payload, retries=5) {
for (let i=0; i<retries; i++) {
const res = await post('/chat-messages', payload);
if (res.status !== 429) return res;
await sleep(Math.min(1000*2**i, 30000) + Math.random()*500);
}
throw new Error('Rate limit exceeded after retries');
} Defensive patterns
Strategy: retry
Try / catch
async function chatWithBackoff(installedAppId, payload, maxRetries = 5) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
return await postChatMessage(installedAppId, payload);
} catch (e) {
if (e.code === 'rate_limit_error' && attempt < maxRetries) {
const delay = Math.min(1000 * 2 ** attempt, 30000) + Math.random() * 500;
await new Promise(r => setTimeout(r, delay));
continue;
}
throw e;
}
}
} Prevention
- Implement client-side rate limiting to stay under the provider's RPM/TPM caps.
- Use exponential backoff with jitter for 429 responses — never retry immediately.
- If rate limits are hit consistently, upgrade the provider plan or use a dedicated key for the installed app.
When it happens
Trigger: POST /console/explore/installed-apps/<installed_app_id>/chat-messages sent at a frequency exceeding the model provider's rate limit (RPM/TPM), or when a shared provider key is being consumed by many concurrent users/tenants simultaneously.
Common situations: Multiple installed apps share the same provider key and collectively exceed the key's RPM; a burst of chat messages from the same tenant; the provider plan tier has a low RPM cap; automated test or load-test scripts hammering the endpoint without throttling.
Related errors
AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12).
Data as JSON: /api/errors/57ec48667723fa94.
Report an issue: GitHub.