Skip to content

Stop usage chips flashing and back off retries for failing providers#8772

Merged
brennanb2025 merged 2 commits into
mainfrom
brennanb2025/fix-usage-bar-display
Jul 14, 2026
Merged

Stop usage chips flashing and back off retries for failing providers#8772
brennanb2025 merged 2 commits into
mainfrom
brennanb2025/fix-usage-bar-display

Conversation

@brennanb2025

Copy link
Copy Markdown
Contributor

Problem

When any usage provider is persistently failing (bad auth, unsupported plan), the status bar becomes a permanent light show — captured on video: chips flip to a loading "…" state for 15+ seconds, flash an error ("Refresh failed" / "Refreshing sign-in" / "Limited"), then flip back, forever. Two mechanisms cause it:

  1. Every refetch repaints all providers as fetching — a settled error chip with no data renders as the loading "…" chip for the whole in-flight window (15s when Codex burns its hidden-PTY timeout), then flashes back to the error.
  2. Error providers on the fast activation-retry lane (claude/codex/grok) retry every 30s on any focus/show/restore event — forever. Verified live: each window focus spawned a hidden codex PTY under the main process lasting exactly 15s. The repeated bursts also drove Claude's tight-budget OAuth usage endpoint into 429s, flipping its chip between "Limited" and its underlying error.

Fix (service-level only, no renderer changes)

  • withFetchingStatus keeps settled states (ok/error/unavailable) visible until the new result actually lands. Only providers with no settled state (first load, explicit account-switch clears, MiniMax credential invalidation) show the loading chip.
  • Activation retries back off exponentially per consecutive applied failure: 30s → 60s → 120s → … capped at the 15-minute poll cadence. The streak resets on any success/unavailable result and on account/target switches. The 5-minute full-fetch lane for providers without a dedicated cycle is unchanged.
  • Manual refresh (refresh() force paths) is untouched — user-initiated recovery stays immediate.

Testing

  • Updated the activation-throttle test to pin the exponential schedule (30s blocked → 60s fires → 120s window).
  • New: backoff resets after recovery; settled error chips never pass through fetching during background refetches (regression test for the flash).
  • vitest run rate-limits + status-bar suites — 469 tests pass; typecheck:tsc:node clean.

Related

Companion fixes for the underlying provider failures: #8765 (Codex auth classification), #8767 (Claude stale scoped keychain), #8769 (Grok unified billing).

Two behaviors made the status bar unusable when any provider was
persistently failing (bad auth, unsupported plan):

1. Every refetch repainted all providers as 'fetching', so a settled
   error chip flashed to a loading "…" chip and back on every cycle.
   withFetchingStatus now keeps settled states (ok/error/unavailable)
   visible until the new result lands; only providers with no settled
   state (first load, explicit account-switch clear) show loading.

2. Error providers on the fast activation-retry lane (claude/codex/
   grok) were retried every 30s on any focus/show/restore event —
   forever. Repeated hits drove Claude's tight-budget usage endpoint
   into 429s, flipping the chip between 'Limited' and its actual error.
   Retries now back off exponentially per consecutive applied failure
   (30s, 60s, 120s, … capped at the 15-minute poll cadence) and reset
   on success or account/target switch.
@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@brennanb2025, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 9 seconds

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: a073aa8a-e67c-4fd4-8123-b94cc451e6a3

📥 Commits

Reviewing files that changed from the base of the PR and between bd47e7c and 2430785.

📒 Files selected for processing (3)
  • src/main/rate-limits/service.test.ts
  • src/main/rate-limits/service.ts
  • src/renderer/src/components/stats/GrokUsagePane.tsx
📝 Walkthrough

Walkthrough

Adds per-provider consecutive failure streak tracking to drive exponential backoff for active-window retry fetches when a provider is in an error state, capped by new constants. Streaks reset on Codex/Claude account or target changes and update after each fetch cycle (full, Codex-only, Claude-only, Grok-only) based on result status. The fetching-status helper now preserves already-settled ok, error, or unavailable states instead of overwriting them during background refetches. Tests are renamed and expanded to cover backoff window doubling, streak reset after recovery, and prevention of transient fetching status flashes.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers the problem, fix, and testing, but omits required template sections like Summary, Screenshots, AI Review Report, Security Audit, and Notes. Add the missing template sections, especially Summary, Screenshots or 'No visual change', AI Review Report, Security Audit, and Notes with cross-platform checks.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately reflects the two main changes: stopping chip flashing and adding retry backoff for failing providers.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 52ba70c0-54a0-472b-8513-8818457cd041

📥 Commits

Reviewing files that changed from the base of the PR and between 3453179 and bd47e7c.

📒 Files selected for processing (2)
  • src/main/rate-limits/service.test.ts
  • src/main/rate-limits/service.ts

Comment thread src/main/rate-limits/service.test.ts Outdated
… feedback

- Stamp failing providers' activation-retry clocks when a stale-driven full
  fetch runs, so the individual failure lane does not fire a redundant retry
  right after the full fetch already retried them.
- GrokUsagePane: manual refresh spinner/disable is now renderer-local, since
  settled snapshots no longer repaint as 'fetching' during refetches.
- Strengthen the backoff-reset test so it distinguishes a reset streak from a
  stale retry timestamp (CodeRabbit), and add a regression test for the
  full-fetch retry stamping.
@brennanb2025 brennanb2025 merged commit dfabd85 into main Jul 14, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant