n8n-io/n8n · warning · OperationalError
Rate limit exceeded. Please wait a moment and try again.
Error message
Rate limit exceeded. Please wait a moment and try again.
What it means
OperationalError thrown by handleStreamError when isLlmQuotaOrRateLimitError returns true, i.e. the underlying error object has status === 429. The message comes from sanitizeLlmErrorMessage, which replaces provider internals with 'Rate limit exceeded. Please wait a moment and try again.' It is classified OperationalError (warning level) so it does not reach Sentry, since users cannot act on provider-side throttling.
Source
Thrown at packages/@n8n/ai-workflow-builder.ee/src/workflow-builder-agent.ts:594
},
streamConfig,
);
// LangGraph's stream has a complex type that doesn't match our StreamEvent definition,
// but at runtime it produces the correct shape based on streamMode configuration.
// With streamMode: ['updates', 'custom'] and subgraphs enabled, events are:
// - Subgraph events: [namespace[], streamMode, data]
// - Parent events: [streamMode, data]
return stream as AsyncIterable<StreamEvent>;
}
private handleStreamError(error: unknown): never {
const invalidRequestErrorMessage = this.getInvalidRequestError(error);
if (invalidRequestErrorMessage) {
throw new ValidationError(invalidRequestErrorMessage);
}
if (this.isLlmQuotaOrRateLimitError(error)) {
throw new OperationalError(sanitizeLlmErrorMessage(error), {
cause: error instanceof Error ? error : undefined,
});
}
throw error;
}
private async *processAgentStream(
stream: Awaited<ReturnType<typeof this.createAgentStream>>,
agent: ReturnType<typeof this.createWorkflow>,
threadConfig: RunnableConfig,
) {
try {
const streamProcessor = createStreamProcessor(stream);
for await (const output of streamProcessor) {
yield output;
}
} catch (error) {View on GitHub (pinned to 5ac6606e81)
Solutions
- Wait a short interval and resend the same message.
- Reduce concurrency of AI builder requests if multiple users/scripts drive it.
- Check the n8n plan's AI message quota and request an increase if persistently hit.
- Inspect the cause on the OperationalError for provider-specific retry-after hints.
Defensive patterns
Strategy: retry
Validate before calling
// Respect a retry-after if available before retrying
function getRetryAfterMs(e: unknown): number {
const headers = (e as any)?.response?.headers ?? {};
const ra = headers['retry-after'];
if (ra) return Number(ra) * 1000;
return 2000;
} Type guard
const isRateLimitError = (e: unknown): boolean =>
!!e && typeof e === 'object' && 'status' in e && (e as { status: number }).status === 429; Try / catch
for (let attempt = 0; attempt < 3; attempt++) {
try {
yield* builder.chat(payload);
break;
} catch (e) {
if (e instanceof OperationalError && /Rate limit exceeded/.test(e.message)) {
await sleep(1000 * 2 ** attempt);
continue;
}
throw e;
}
} Prevention
- Throttle concurrent AI builder requests to stay under provider limits.
- Honour any Retry-After header surfaced on the cause.
- Surface a 'please wait' UX instead of failing immediately on 429.
When it happens
Trigger: The LLM provider behind the AI workflow builder returns HTTP 429 (rate limit or quota exhausted) during agent.stream. handleStreamError catches it, sanitizes the message to avoid leaking provider detail, and rethrows as OperationalError with the original error as cause.
Common situations: Shared n8n.cloud capacity spike; a tenant exceeding its AI message quota; bursts of concurrent workflow-builder requests; the upstream provider (OpenAI/Anthropic via the proxy) throttling the n8n backend.
Related errors
- Message exceeds maximum length of ${MAX_AI_BUILDER_PROMPT_LE
- The current conversation and workflow state is too large to
- admittance_rejected
- admittance_rejected
- OpenAI: Rate limit reached
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/35cbe43c37087548.
Report an issue: GitHub.