Skip to content

Handle Claude rate limits and throttle provider fetches#102

Merged
kargnas merged 1 commit intomainfrom
codex-claude-rate-limit-guard
Mar 6, 2026
Merged

Handle Claude rate limits and throttle provider fetches#102
kargnas merged 1 commit intomainfrom
codex-claude-rate-limit-guard

Conversation

@kargnas
Copy link
Member

@kargnas kargnas commented Mar 6, 2026

Summary

Claude usage fetches were failing with 429 responses from the Anthropic usage endpoint, but the app surfaced those failures as generic errors and kept retrying on the normal refresh cadence. That left users without a clear explanation in the menu and increased the chance of repeated rate-limited requests.

Root Cause

The Claude provider treated 429 responses like any other network failure, so the UI could only show a generic failure state. The provider manager also had no provider-specific minimum fetch interval, which meant Claude could be retried on the standard auto-refresh cadence even immediately after a rate-limit response. In parallel, the refresh path needed an explicit guard against overlapping startup refresh scheduling and concurrent provider fetches.

Fix

This change adds a provider-level minimum fetch interval to the shared protocol and sets Claude to a ten minute cooldown. Claude now parses API error payloads, classifies 429 responses as rate limits, and surfaces a user-facing Rate limited state instead of collapsing into a generic failure. The provider manager now tracks in-flight fetches per provider, deduplicates concurrent requests, and returns throttled cooldown messages instead of issuing another network call while the cooldown window is active. The status bar menu was updated to render rate-limited providers explicitly, including an error submenu and cached details when available. The refresh timer startup path now cancels any previous initial refresh task before scheduling a new one.

User Impact

Users will now see Claude marked as Rate limited when Anthropic rejects usage requests with 429, instead of seeing a vague failure. Subsequent refreshes during the cooldown window do not hit the Claude usage API again, which reduces unnecessary retries and avoids amplifying the rate-limit condition. The runtime fetch path also resists duplicate refreshes more cleanly by joining concurrent provider requests instead of spawning duplicate network work.

Validation

I validated the change with swiftlint lint CopilotMonitor/CopilotMonitor CopilotMonitor/CopilotMonitorTests, xcodebuild test -project CopilotMonitor/CopilotMonitor.xcodeproj -scheme CopilotMonitor -destination 'platform=macOS', and xcodebuild clean build -project CopilotMonitor/CopilotMonitor.xcodeproj -scheme CopilotMonitor -destination 'platform=macOS'. I also launched the rebuilt debug app, confirmed that Claude rendered as Rate limited in the menu, and observed that the next three-minute refresh returned Rate limited. Retrying in 7m. from the throttled path instead of issuing another Claude network request.

@kargnas kargnas marked this pull request as ready for review March 6, 2026 19:23
@op-gg-ai-devops
Copy link
Contributor

Claude API Rate Limit(429) 대응하려고 Provider 요청 스로틀링이랑 중복 호출 제거 로직 추가하고, UI에 에러 상태 표시 기능 넣었네.


야, 코드는 전체적으로 꽤 잘 짰다. 특히 ProviderManager에서 inFlightFetches 써서 동시에 들어오는 요청 하나로 퉁치고, 스로틀링으로 쿨타임 돌리는 로직은 아주 훌륭해. Claude 429 떨어지면 10분(minimumFetchInterval) 동안 숨 참게 만든 것도 API 보호 차원에서 적절하고. 다만 StatusBarController에 에러 분기 처리 로직이 계속 늘어나면서 좀 지저분해 보이는데, 이건 나중에 뷰 모델로 따로 빼서 정리 좀 하는 게 좋겠다.

이건 맛보기 리뷰고, 버그나 보안 이슈 포함한 깐깐한 전체 리뷰 마렵다 싶으면 댓글로 @op-gg-ai-devops 리뷰해줘 라고 쓰거나 Reviewer에 나 추가해라. (AGENTS.md 규칙 있으면 그거 따름)

@kargnas kargnas merged commit 59e88d4 into main Mar 6, 2026
15 checks passed
@kargnas kargnas deleted the codex-claude-rate-limit-guard branch March 6, 2026 19:25
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