langgenius/dify · warning · InvokeRateLimitHttpError
rate_limit_error
rate_limit_error
Error message
Rate Limit Error
What it means
Raised as InvokeRateLimitHttpError (HTTP 400, code 'rate_limit_error') from the AdvancedChatDraftWorkflowRunApi.post handler at POST /apps/{app_id}/advanced-chat/workflows/draft/run when AppGenerateService.generate triggers the per-tenant/per-app rate limiter during an advanced-chat draft debug run. The underlying core.error.InvokeRateLimitError carries a description string that is forwarded verbatim to the HTTP error. It signals the debug-run invocation exceeded the configured invocation quota, not a model provider 429.
Source
Thrown at api/controllers/console/app/workflow.py:730
args["external_trace_id"] = external_trace_id
try:
response = AppGenerateService.generate(
session=session,
app_model=app_model,
user=current_user,
args=args,
invoke_from=InvokeFrom.DEBUGGER,
streaming=True,
)
return helper.compact_generate_response(response)
except services.errors.conversation.ConversationNotExistsError:
raise NotFound("Conversation Not Exists.")
except services.errors.conversation.ConversationCompletedError:
raise ConversationCompletedError()
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("/apps/<uuid:app_id>/advanced-chat/workflows/draft/iteration/nodes/<string:node_id>/run")
class AdvancedChatDraftRunIterationNodeApi(Resource):
@console_ns.doc("run_advanced_chat_draft_iteration_node")
@console_ns.doc(description="Run draft workflow iteration node for advanced chat")
@console_ns.doc(params={"app_id": "Application ID", "node_id": "Node ID"})
@console_ns.expect(console_ns.models[IterationNodeRunPayload.__name__])
@console_ns.response(
200,
"Iteration node run started successfully",
console_ns.models[GeneratedAppResponse.__name__],
)View on GitHub (pinned to ef8544b173)
Solutions
- Back off and retry the same draft run after the limiter window elapses; the response description states the wait.
- Check the rate-limit configuration for the workspace/tenant and raise the cap if the legitimate debug load needs it.
- Stop duplicate concurrent run requests from the client (debounce the run button, cancel in-flight requests).
- Inspect server logs to confirm the limiter key (tenant/app/user) and identify which caller is saturating it.
Example fix
// before: client retries immediately on any error
async function runDraft() {
await fetch(`/apps/${appId}/advanced-chat/workflows/draft/run`, {method:'POST', body});
}
// after: honor Retry-After / back off on rate_limit_error
async function runDraft() {
const r = await fetch(url, {method:'POST', body});
if (r.status === 400 && (await r.json()).code === 'rate_limit_error') {
await sleep(backoffMs()); return;
}
} Defensive patterns
Strategy: retry
Validate before calling
// Before the call, gate on a client-side token bucket sized to the known workspace limit.
const bucket = makeTokenBucket({capacity: RATE_LIMIT, refillPerSec: REFILL});
async function safeDraftRun(appId, body) {
if (!bucket.tryConsume(1)) {
return {skip: true, retryInMs: bucket.timeUntilNext()};
}
return fetch(`/console/apps/${appId}/advanced-chat/workflows/draft/run`, {method:'POST', body: JSON.stringify(body)});
} Try / catch
// Honor the rate-limit description / back off; surface to UI as throttled.
try {
return await runDraftRun(appId, body);
} catch (e) {
if (isHttpError(e, 400, 'rate_limit_error')) {
scheduleRetry(e.description); // parse wait from description
return;
}
throw e;
} Prevention
- Debounce the debug-run button and cancel in-flight requests.
- Track the rate-limit window client-side and disable the run button while cooling down.
- Coordinate shared-tenant load with team members during heavy debugging.
When it happens
Trigger: Issuing repeated POST /apps/{app_id}/advanced-chat/workflows/draft/run (streaming debugger) faster than the workspace's rate-limit window allows; the limiter trips inside AppGenerateService.generate before the SSE stream is returned.
Common situations: Auto-retry loops in the workflow debugger, a stuck frontend re-firing the run on error, shared dev tenant hammered by several developers, or rate-limit config (e.g. dify_config invocation quotas) set too low for the workload.
Related errors
- The server encountered an internal error and was unable to c
- missing inputs
- Conversation Not Exists.
- conversation_completed
- Workflow not initialized
AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12).
Data as JSON: /api/errors/36b4f514df031eef.
Report an issue: GitHub.