nexu-io/open-design · warning · ConnectorServiceError
CONNECTOR_RATE_LIMITED
CONNECTOR_RATE_LIMITED
Error message
connector tool run call limit exceeded
What it means
Thrown by ConnectorService.enforceRunLimits() with HTTP 429 when a run (context.runId) has already consumed CONNECTOR_RUN_TOTAL_CALL_LIMIT (60) connector tool calls across its entire lifetime (TTL CONNECTOR_RUN_LIMIT_TTL_MS = 15 min). It is the hard ceiling — independent of rate windows — to bound total connector spend per run. details carries runId and totalCallLimit. Calls with runId === undefined bypass enforcement entirely.
Source
Thrown at apps/daemon/src/connectors/service.ts:876
throw new ConnectorServiceError('CONNECTOR_EXECUTION_FAILED', 'connector provider is not implemented', 501, {
connectorId: request.connectorId,
toolName: request.toolName,
});
}
private enforceRunLimits(context: ConnectorExecutionContext): void {
if (context.runId === undefined) return;
const now = Date.now();
this.pruneRunLimits(now);
const key = connectorRunLimitKey(context);
const current = this.runLimits.get(key);
const state: ConnectorRunLimitState = current === undefined || now - current.windowStartedAt >= CONNECTOR_RUN_RATE_LIMIT_WINDOW_MS
? { windowStartedAt: now, lastSeenAt: now, windowCalls: 0, totalCalls: current?.totalCalls ?? 0 }
: current;
if (state.totalCalls >= CONNECTOR_RUN_TOTAL_CALL_LIMIT) {
throw new ConnectorServiceError('CONNECTOR_RATE_LIMITED', 'connector tool run call limit exceeded', 429, {
runId: context.runId ?? null,
totalCallLimit: CONNECTOR_RUN_TOTAL_CALL_LIMIT,
});
}
if (state.windowCalls >= CONNECTOR_RUN_RATE_LIMIT_CALLS) {
throw new ConnectorServiceError('CONNECTOR_RATE_LIMITED', 'connector tool rate limit exceeded', 429, {
runId: context.runId ?? null,
rateLimit: CONNECTOR_RUN_RATE_LIMIT_CALLS,
windowMs: CONNECTOR_RUN_RATE_LIMIT_WINDOW_MS,
});
}
state.windowCalls += 1;
state.totalCalls += 1;
state.lastSeenAt = now;
this.runLimits.set(key, state);
}
View on GitHub (pinned to 5be4028344)
Solutions
- Reduce the number of connector calls in the run: cache results, batch where the tool supports it, prune no-op calls.
- Start a new run if the work legitimately exceeds 60 calls — the limit is keyed per runId.
- If the limit must be raised for a sanctioned workload, change CONNECTOR_RUN_TOTAL_CALL_LIMIT in apps/daemon/src/connectors/service.ts (requires a deliberate config change, not a runtime override).
Example fix
// before: calling connector tools in an unbounded loop
while (!done) { await execute(req, { ...ctx, runId }); }
// after: cap calls per run and hand off to a new run when exhausted
let calls = 0;
while (!done) {
if (calls >= CONNECTOR_RUN_TOTAL_CALL_LIMIT) { runId = await startNewRun(); calls = 0; }
await execute(req, { ...ctx, runId }); calls++;
} Defensive patterns
Strategy: try-catch
Validate before calling
// Track per-run call counts and stop before the total cap
const callsThisRun = runCallCounts.get(context.runId) ?? 0;
if (context.runId !== undefined && callsThisRun >= CONNECTOR_RUN_TOTAL_CALL_LIMIT) {
throw new Error(`run ${context.runId} at total call limit; start a new run`);
}
runCallCounts.set(context.runId, callsThisRun + 1);
await connectorService.execute(request, context); Type guard
function runHasBudget(counts: Map<string, number>, runId: string | undefined): boolean {
return runId === undefined || (counts.get(runId) ?? 0) < CONNECTOR_RUN_TOTAL_CALL_LIMIT;
} Try / catch
try { await connectorService.execute(request, context); }
catch (e) {
if (e instanceof ConnectorServiceError && e.code === 'CONNECTOR_RATE_LIMITED' && (e.details as any)?.totalCallLimit) {
// start a new run (new runId) and continue, or terminate the workflow
} else throw e;
} Prevention
- Cache connector outputs inside the run so the same call is not repeated.
- Cap agent loop iterations to stay under CONNECTOR_RUN_TOTAL_CALL_LIMIT.
- Surface remaining budget to the agent so it can prioritize high-value calls.
When it happens
Trigger: An agent run (runId set) issues its 61st connector tool call within the 15-minute TTL window; the per-run counter (state.totalCalls) reached CONNECTOR_RUN_TOTAL_CALL_LIMIT.
Common situations: A long agentic loop keeps calling connector tools without termination; a tool retries in a tight loop; the run genuinely needs more connector calls than the budget allows.
Related errors
- CONNECTOR_OUTPUT_TOO_LARGE
- CONNECTOR_NOT_FOUND
- CONNECTOR_EXECUTION_FAILED
- CONNECTOR_DISABLED
- CONNECTOR_NOT_CONNECTED
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/ce44b5bc80db95d5.
Report an issue: GitHub.