Skip to content

Add error handling for Claude Code quota API failures#251

Merged
AnnatarHe merged 1 commit intomainfrom
claude/fix-oauth-error-handling-IdoVR
Mar 6, 2026
Merged

Add error handling for Claude Code quota API failures#251
AnnatarHe merged 1 commit intomainfrom
claude/fix-oauth-error-handling-IdoVR

Conversation

@AnnatarHe
Copy link
Copy Markdown
Contributor

@AnnatarHe AnnatarHe commented Mar 6, 2026

Summary

This PR adds error tracking and display for Claude Code quota/rate limit API failures. When the quota API fails to fetch data, users now see a descriptive error message in the statusline instead of a blank indicator.

Key Changes

  • Error tracking in rate limit cache: Added lastError field to anthropicRateLimitCache to store shortened error descriptions
  • Error shortening utility: Implemented shortenAPIError() function that converts API errors into concise statusline-friendly strings:
    • HTTP status errors → api:XXX (e.g., api:403)
    • Decode errors → api:decode
    • Network errors → network
    • OAuth failures → oauth
  • Error propagation: Modified fetchRateLimit() to capture and cache errors when OAuth token fetch or API calls fail
  • Statusline display: Updated formatQuotaPart() to accept and display error messages in red when quota data is unavailable
  • Socket response: Extended CCInfoResponse to include QuotaError field for communicating errors to clients
  • Error priority: Data takes priority over errors—if quota data is successfully fetched, errors are cleared and not displayed

Implementation Details

  • Errors are stored with mutex protection in the rate limit cache
  • The error display only appears when quota data is nil; successful data fetches clear the error state
  • Error messages are color-coded red to indicate problems
  • All changes are backward compatible with existing quota display logic
  • Comprehensive test coverage added for error handling scenarios

https://claude.ai/code/session_01H6KrQwMmpvN87z7mMsF57u


Open with Devin

When fetchClaudeCodeOAuthToken or fetchAnthropicUsage fails, the error
was silently swallowed and users only saw "🚦 -" with no indication of
what went wrong. Now errors are cached in the daemon, propagated via
the CCInfoResponse, and displayed as short messages like "🚦 err:oauth"
or "🚦 err:api:403" in the statusline.

Closes #250

https://claude.ai/code/session_01H6KrQwMmpvN87z7mMsF57u
@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the user experience by implementing robust error handling for Claude Code quota API failures. Instead of displaying a blank or missing indicator, users will now see a descriptive, color-coded error message in the statusline when the quota API encounters issues. This change provides immediate and actionable feedback, improving transparency and helping users understand why quota information might not be available.

Highlights

  • Error Tracking: Introduced a lastError field in anthropicRateLimitCache to store concise error descriptions related to Claude Code quota API failures.
  • Error Shortening Utility: Implemented shortenAPIError() to convert detailed API errors (HTTP status, decode, network, OAuth) into brief, statusline-friendly strings.
  • Error Propagation and Caching: Modified fetchRateLimit() to capture and cache errors during OAuth token retrieval or Anthropic API calls, and to clear errors upon successful data fetches.
  • Statusline Display: Updated formatQuotaPart() to accept and display these shortened error messages in red within the statusline when quota data is unavailable.
  • Socket Communication: Extended the CCInfoResponse struct with a QuotaError field to communicate API errors to client applications.
Changelog
  • commands/cc_statusline.go
    • Added QuotaError field to ccStatuslineResult and statuslineParams structs.
    • Modified commandCCStatusline to pass the QuotaError.
    • Updated formatStatuslineOutput to pass QuotaError to formatQuotaPart.
    • Changed formatQuotaPart signature to accept quotaError and display it in red when utilization data is nil.
  • commands/cc_statusline_test.go
    • Updated existing formatQuotaPart test calls to include the new quotaError parameter.
    • Added new test cases for formatQuotaPart to verify error display for 'oauth' and 'api:403' errors.
    • Included a test case to confirm that errors are ignored when quota data is successfully present.
  • daemon/anthropic_ratelimit.go
    • Added a lastError string field to the anthropicRateLimitCache struct for storing short error descriptions.
  • daemon/anthropic_ratelimit_test.go
    • Imported the fmt package.
    • Added test functions for shortenAPIError to cover HTTP status, decode, and network error scenarios.
    • Included test functions for GetCachedRateLimitError to check empty and error-present states.
  • daemon/cc_info_timer.go
    • Imported the fmt package.
    • Modified fetchRateLimit to store 'oauth' error if token fetching fails.
    • Updated fetchRateLimit to store a shortened API error using shortenAPIError if Anthropic usage fetching fails.
    • Ensured lastError is cleared in fetchRateLimit upon successful rate limit data retrieval.
    • Added GetCachedRateLimitError method to retrieve the cached error string.
    • Implemented shortenAPIError function to convert various error types into concise strings for statusline display.
  • daemon/socket.go
    • Added QuotaError field to the CCInfoResponse struct.
    • Modified handleCCInfo to populate the QuotaError field in the response if rate limit data is not available.
Activity
  • Comprehensive test coverage was added for the new error handling scenarios.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request effectively adds error handling for the Claude Code quota API. The changes are well-structured, propagating the error information from the daemon up to the statusline display. The inclusion of new fields in the data structures (ccStatuslineResult, CCInfoResponse, etc.) is consistent, and the logic to display errors only when data is unavailable is sound. The test coverage for the new error handling scenarios is also comprehensive.

I have one suggestion in daemon/cc_info_timer.go to improve the robustness of error parsing. Overall, this is a solid implementation.

Comment thread daemon/cc_info_timer.go
Comment on lines +565 to +567
if len(msg) >= 6 && msg[:6] == "failed" {
return "api:decode"
}
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.

medium

While parsing error strings works, it can be brittle if the error message format changes. Using strings.HasPrefix is more idiomatic and slightly more robust than checking the length and slicing. Making the prefix check more specific also reduces the chance of false positives.

For a more robust long-term solution, consider introducing typed errors. This would allow you to use errors.As for type-safe error checking, avoiding string parsing altogether.

You will need to add import "strings" at the top of the file for the suggestion to work.

Suggested change
if len(msg) >= 6 && msg[:6] == "failed" {
return "api:decode"
}
if strings.HasPrefix(msg, "failed to decode") {
return "api:decode"
}

@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 6, 2026

Codecov Report

❌ Patch coverage is 66.66667% with 9 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
daemon/cc_info_timer.go 63.15% 7 Missing ⚠️
commands/cc_statusline.go 66.66% 2 Missing ⚠️
Flag Coverage Δ
unittests 37.58% <66.66%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
daemon/anthropic_ratelimit.go 0.00% <ø> (ø)
daemon/socket.go 61.65% <100.00%> (+0.58%) ⬆️
commands/cc_statusline.go 58.65% <66.66%> (+0.37%) ⬆️
daemon/cc_info_timer.go 73.07% <63.15%> (-0.65%) ⬇️

... and 2 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 potential issue.

View 3 additional findings in Devin Review.

Open in Devin Review

Comment thread daemon/cc_info_timer.go
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 lastError not cleared in stopTimer, causing stale error display after inactivity restart

The stopTimer() method at daemon/cc_info_timer.go:150-154 clears usage, fetchedAt, and lastAttemptAt from the rate limit cache, but does not clear the newly added lastError field. After the timer stops due to inactivity and a new client triggers a restart, GetCachedRateLimit() returns nil (usage was cleared) while GetCachedRateLimitError() returns a stale error string from the previous session. This causes handleCCInfo at daemon/socket.go:257-258 to surface a stale error in the statusline, even though the previous error may no longer be relevant.

(Refers to lines 150-154)

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@AnnatarHe AnnatarHe merged commit 2f54fd2 into main Mar 6, 2026
7 checks passed
@AnnatarHe AnnatarHe deleted the claude/fix-oauth-error-handling-IdoVR branch March 6, 2026 04:57
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.

2 participants