langgenius/dify · warning · InvokeRateLimitHttpError
rate_limit_error
rate_limit_error
Error message
Rate Limit Error
What it means
Returned (HTTP 429, error_code `rate_limit_error`, 'Rate Limit Error') by POST /rag/pipelines/<pipeline_id>/workflows/draft/run when `PipelineGenerateService.generate` raises `services.errors.llm.InvokeRateLimitError`. This signals that the underlying LLM provider (or Dify's own rate limiter) rejected the request because the tenant/app/user exceeded the configured invocation rate. The controller translates it to the HTTP-layer `InvokeRateLimitError`.
Source
Thrown at api/controllers/console/datasets/rag_pipeline/rag_pipeline_workflow.py:368
"""
Run draft workflow
"""
pipeline = load_rag_pipeline(session, str(pipeline_id))
args = req_data.model_dump()
try:
response = PipelineGenerateService.generate(
session=session,
pipeline=pipeline,
user=current_user,
args=args,
invoke_from=InvokeFrom.DEBUGGER,
streaming=True,
)
return helper.compact_generate_response(response)
except InvokeRateLimitError as ex:
raise InvokeRateLimitHttpError(ex.description)
@console_ns.route("/rag/pipelines/<uuid:pipeline_id>/workflows/published/run")
class PublishedRagPipelineRunApi(Resource):
@console_ns.expect(console_ns.models[PublishedWorkflowRunPayload.__name__])
@console_ns.response(200, "Success", console_ns.models[RagPipelineOpaqueResponse.__name__])
@setup_required
@login_required
@account_initialization_required
@edit_permission_required
@rbac_permission_required(RBACResourceScope.DATASET, RBACPermission.DATASET_EDIT)
@with_current_user
@with_session
@model_validate(PublishedWorkflowRunPayload)
def post(self, req_data: PublishedWorkflowRunPayload, session: Session, current_user: Account, pipeline_id: UUID):
"""
Run published workflow
"""View on GitHub (pinned to ef8544b173)
Solutions
- Back off and retry with exponential jitter; honor Retry-After if the provider supplies it.
- Reduce concurrency of draft runs (serialize debugger invocations).
- Upgrade or reconfigure the model provider quota, or switch to a higher-tier key.
- Cache draft run results during iterative development to avoid redundant invocations.
Example fix
// before
await post(`${base}/draft/run`, payload)
// after
async function runDraftWithBackoff(payload, retries = 4) {
for (let i = 0; i < retries; i++) {
try {
return await post(`${base}/draft/run`, payload)
} catch (e) {
if (e.code !== 'rate_limit_error') throw e
await sleep(Math.min(1000 * 2 ** i, 8000) + Math.random() * 200)
}
}
throw new Error('draft run rate-limited after retries')
} Defensive patterns
Strategy: retry
Validate before calling
// serialize debugger runs to stay under the rate limit
const queue = new ConcurrencyQueue({ concurrency: 1, minIntervalMs: 1000 })
await queue.add(() => post(`${base}/draft/run`, payload)) Try / catch
try {
return await post(`${base}/draft/run`, payload)
} catch (e) {
if (e.code === 'rate_limit_error') {
const wait = e.retryAfter ?? Math.min(1000 * 2 ** attempt, 8000)
await sleep(wait + Math.random() * 200)
return post(`${base}/draft/run`, payload) // bounded retry
}
throw e
} Prevention
- Serialize draft runs during iterative development to avoid bursts.
- Cache previous run outputs to skip redundant invocations.
- Tune provider quotas to match expected debugger concurrency.
- Always retry 429 with exponential backoff and jitter.
When it happens
Trigger: Burst-running draft workflows against a provider with a low TPM/RPM quota; many concurrent debugger runs; a downstream provider returning 429; Dify's own rate-limit middleware tripping on the tenant.
Common situations: Tight provider quotas (sandbox, trial keys). Load tests hammering the draft run endpoint. A single user repeatedly testing a chatty workflow. Shared provider key across multiple pipelines.
Related errors
- expected dict for file, got {type(raw_value)}
- expected list for files, got {type(raw_value)}
- expected dict for files[0], got {type(raw_value)}
- Draft workflow not found, pipeline_id={pipeline.id}
- draft_workflow_not_exist
AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12).
Data as JSON: /api/errors/271b2acddda31ab8.
Report an issue: GitHub.