stablyai/orca · warning

GitHub ${bucket} rate limit is low; retry after ${new Date(g

Error message

GitHub ${bucket} rate limit is low; retry after ${new Date(guard.resetAt * 1000).toLocaleTimeString()}

What it means

Thrown by assertRateLimitBudget as a client-side pre-flight guard before spending GitHub API quota. When spendsSharedGitHubComQuota is true it refreshes the rate-limit snapshot, then repositoryRateLimitGuard reports blocked=true for the named bucket (core or graphql). The error is proactive — no request has been made yet — and includes the reset time so callers can schedule a retry. It protects a per-user, per-hour budget shared between Orca, the user's own gh CLI, and any other agents.

Source

Thrown at src/main/github/client.ts:249

    const oldestKey = repositoryMergeMetadataCache.keys().next().value
    if (oldestKey === undefined) {
      break
    }
    repositoryMergeMetadataCache.delete(oldestKey)
  }
}

async function assertRateLimitBudget(
  bucket: RateLimitBucketKind,
  repository?: GitHubApiRepository | null,
  executionOptions?: Pick<GhExecOptions, 'cwd' | 'wslDistro'>
): Promise<void> {
  if (spendsSharedGitHubComQuota(repository, executionOptions)) {
    await getRateLimit()
  }
  const guard = repositoryRateLimitGuard(repository, bucket, executionOptions)
  if (guard.blocked) {
    throw new Error(
      `GitHub ${bucket} rate limit is low; retry after ${new Date(guard.resetAt * 1000).toLocaleTimeString()}`
    )
  }
}

// Why: a branch lookup prefers REST but can fall back to `gh pr list` and
// `gh pr view`, so both buckets are guarded and charged. Mirrors the PR refresh
// coordinator's own estimate.
const PR_BRANCH_LOOKUP_BUCKETS = ['core', 'graphql'] as const

/**
 * Rate-limit floor for GitHub PR lookups that do not run through the PR refresh
 * coordinator's queue (#11532).
 *
 * The coordinator guards and paces its own background refreshes, but
 * `hostedReview:forBranch` polls the same lookup straight from the renderer.
 * Ungated, the two paths together could spend the user's entire hourly quota —
 * which is per user and shared with their own `gh` and CLI agents.

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Wait until the reset time shown in the message, then retry — the guard will re-evaluate.
  2. Reduce background refresh frequency in Orca settings to lower steady-state spend.
  3. If you are running other gh CLI tooling, stagger or pause it.
  4. For automated jobs, switch to a GitHub App token (higher limits) or use conditional requests / caching.
  5. Confirm the bucket that is low (core vs graphql) — graphql drains faster for stack-aware PR lookups.

Example fix

// before: caller retries immediately on any error
await lookupPR(number).catch(() => lookupPR(number))

// after: honor the rate-limit reset hint
try {
  await lookupPR(number)
} catch (err) {
  if (/rate limit is low; retry after/.test(String(err.message))) {
    scheduleRetryAfterMessage(err.message)
    return
  }
  throw err
}
Defensive patterns

Strategy: retry

Validate before calling

import { getRateLimit } from './client'
async function budgetAllows(bucket: 'core' | 'graphql'): Promise<boolean> {
  await getRateLimit() // warm snapshot
  return !repositoryRateLimitGuard(undefined, bucket, undefined).blocked
}

Type guard

function isRateLimitError(err: unknown): boolean {
  return err instanceof Error && /rate limit is low; retry after/.test(err.message)
}

Try / catch

try {
  await lookupPR(number)
} catch (err) {
  if (isRateLimitError(err)) {
    const resetAt = parseRetryAfterTime(err.message)
    scheduleRetry(resetAt) // do NOT retry immediately
    return
  }
  throw err
}

Prevention

When it happens

Trigger: Heavy PR refresh polling combined with renderer-driven branch lookups exhausting the hourly core/graphql budget; a large stack of PRs being refreshed at once; running gh CLI in parallel terminals against the same account; secondary rate limits kicking in near the floor.

Common situations: User runs many parallel gh operations; a monorepo with dozens of open PRs all refreshing; CI or other tooling consuming the same token; an org with strict per-user limits.

Related errors


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/bbcce70bfe44e95e. Report an issue: GitHub.