thedotmack/claude-mem · warning

Subscription usage limit hit

Error message

Subscription usage limit hit

What it means

This is a warning log emitted when the SDK observer detects that the Claude subscription usage limit has been hit for the account running the session. The observer runs on the same account as the observed session, and globalRateLimitStore.set() dedupes so only one event is recorded per exhausted window rather than one per observer request. It signals that the user's own Claude Code session is out of usage until the rate-limit window resets.

Solutions

  1. Wait for the rate-limit window to reset, or upgrade the subscription plan/increase limits.
  2. Enable or verify overage billing (overageStatus) so requests continue past the soft cap.
  3. Reduce the number of concurrent observed sessions sharing the same account.
  4. Route work to a different account or API-key-based billing until the window resets.
Defensive patterns

Strategy: validation

Validate before calling

if (globalRateLimitStore.peek?.()?.rateLimitType === 'rejected') {
  // defer session start until the window resets
}

Prevention

When it happens

Trigger: During startSession, when an observer SDK request returns a rate-limit info snapshot with rateLimitType 'rejected' status, indicating the shared account's subscription usage wall is exhausted for the current window.

Common situations: Hitting the 5-hour or weekly Claude subscription cap during heavy automated usage; multiple observed sessions sharing one account exhausting the quota; overage disabled so requests are rejected outright.

Related errors


AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17). Data as JSON: /api/errors/ab663f1ffa8c84b7. Report an issue: GitHub.

Appendix: source

Thrown at src/services/worker/ClaudeProvider.ts:339

      let turnDispatchedText = false;
      // One re-queue per generator pass for a batch a failed turn never read.
      let retriedAfterErrorResult = false;

      for await (const message of queryResult) {
        // Quota-aware wall-clock guard (#2234): the SDK pushes
        // `rate_limit_event` messages carrying live subscription quota state
        // (see extractRateLimitInfo for the shape). Capture the snapshot, then
        // bail out of the loop before issuing another request if we've
        // crossed a per-window threshold. API-key users are exempt — they
        // authorized per-call spend.
        const info = extractRateLimitInfo(message);
        if (info) {
          // The observer runs on the same account as the observed session,
          // so a `rejected` snapshot here means the user's own Claude Code
          // session is out of usage too. set() dedupes: one event per
          // exhausted window, not one per observer request against the wall.
          if (globalRateLimitStore.set(info)) {
            logger.warn('SDK', 'Subscription usage limit hit', {
              sessionDbId: session.sessionDbId,
              window: info.rateLimitType,
              overageStatus: info.overageStatus,
            });
            captureEvent('usage_limit_hit', {
              ...buildUsageLimitHitProps(info),
              ide: session.platformSource,
              provider: 'claude',
              observed_model: session.observedModel,
              observed_billing: session.observedBilling,
            });
          }
          const decision = shouldAbortForQuota(authMethod, globalRateLimitStore);
          if (decision.abort) {
            logger.warn('SDK', `Aborting session for quota guard: ${decision.reason}`, {
              sessionDbId: session.sessionDbId,
              window: decision.window,
              authMethod,

View on GitHub (pinned to d8bc9755e7)