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

  1. Reduce the number of connector calls in the run: cache results, batch where the tool supports it, prune no-op calls.
  2. Start a new run if the work legitimately exceeds 60 calls — the limit is keyed per runId.
  3. 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

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


AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12). Data as JSON: /api/errors/ce44b5bc80db95d5. Report an issue: GitHub.