thedotmack/claude-mem · warning
Aborting session for quota guard: ${decision.reason}
Error message
Aborting session for quota guard: ${decision.reason} What it means
When the SDK emits a rate_limit system message, claude-mem stores the snapshot and consults shouldAbortForQuota(). API-key auth never aborts (per-call billing is pre-authorized), but subscription/OAuth auth aborts when a window (five_hour, seven_day_opus, seven_day_sonnet, seven_day, overage) crosses its utilization threshold or the provider explicitly reports the bucket exhausted/rejected. This warning fires and the observer session is aborted via its AbortController.
Source
Thrown at src/services/worker/ClaudeProvider.ts:319
// 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,
});
session.abortReason = `quota:${decision.window ?? 'unknown'}`;
try {
session.abortController.abort();
} catch {
// best-effort
}
break;
}
}
if (message.session_id && message.session_id !== session.memorySessionId) {
const previousId = session.memorySessionId;
session.memorySessionId = message.session_id;
this.dbManager.getSessionStore().ensureMemorySessionIdRegistered(View on GitHub (pinned to 8bc631a71a)
Solutions
- Wait for the rate-limit window to reset (the guard deliberately stops before burning the last few percent)
- Switch the observer to API-key auth so per-call spend is authorized and the quota guard never aborts
- Reduce consumption: lower observer frequency, close unneeded sessions, or free the busy window before resuming
Example fix
# switch observer to API-key auth so the subscription quota guard does not abort # ~/.claude-mem/.env ANTHROPIC_AUTH_METHOD=api_key ANTHROPIC_API_KEY=sk-ant-...
Defensive patterns
Strategy: validation
Validate before calling
import { shouldAbortForQuota } from './RateLimitStore.js';
function guardBeforeObserverRun(authMethod: string, store: RateLimitStore): void {
const decision = shouldAbortForQuota(authMethod, store);
if (decision.abort) {
throw new Error(`skipping observer run — ${decision.reason}`);
}
} Type guard
function isApiKeyAuth(authMethod: string): boolean {
return authMethod === 'api_key' || authMethod.startsWith('API key');
} Prevention
- Check the rate-limit snapshot before launching observer sessions on subscription auth
- Switch to API-key auth if the observer must run regardless of subscription windows
- Respect the reset-grace window — retrying immediately after an abort just burns the remaining quota
When it happens
Trigger: Subscription auth with the five-hour window near its utilization threshold; a seven-day Opus/Sonnet bucket reported as rejected; overage window exhausted; a reset due within the 15-minute grace buffer while utilization is above the floor.
Common situations: Heavy parallel Claude Code plus observer usage on a Pro/Max plan near quota; weekend sprints exhausting the five-hour window; the observer's background summarization tipping an already-high bucket.
Related errors
- Generator paused for ${abortCategory}; preserving buffered w
- rate_limited
- quota_exceeded
- Anthropic API rejected request with HTTP 400: this model doe
- Skipping resume for INIT prompt despite existing memorySessi
AI-assisted analysis of thedotmack/claude-mem@8bc631a71a (2026-08-20).
Data as JSON: /api/errors/9616393730cab120.
Report an issue: GitHub.