Skip to content
This repository was archived by the owner on Jul 17, 2026. It is now read-only.

fix: classify G1 credit exhaustion as quota#591

Open
eddieparc wants to merge 1 commit into
NoeFabris:mainfrom
eddieparc:codex/g1-resource-exhausted-quota
Open

fix: classify G1 credit exhaustion as quota#591
eddieparc wants to merge 1 commit into
NoeFabris:mainfrom
eddieparc:codex/g1-resource-exhausted-quota

Conversation

@eddieparc

Copy link
Copy Markdown

Summary

  • Classify INSUFFICIENT_G1_CREDITS_BALANCE as QUOTA_EXHAUSTED.
  • Detect the same reason when it appears inside the upstream JSON error message.
  • Add regression coverage for the Gemini/Antigravity 429 RESOURCE_EXHAUSTED payload.

Closes #590.

Validation

npm run typecheck
npm run build
npm test

Result: 35 test files passed, 997 tests passed.

@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: d918508a-2de5-40dc-9ae8-d20935226190

📥 Commits

Reviewing files that changed from the base of the PR and between 740e315 and 6e05ee6.

📒 Files selected for processing (2)
  • src/plugin/accounts.test.ts
  • src/plugin/accounts.ts
📜 Recent review details
⏰ Context from checks skipped due to timeout. (1)
  • GitHub Check: Greptile Review
🔇 Additional comments (2)
src/plugin/accounts.ts (1)

61-61: LGTM!

Also applies to: 71-73

src/plugin/accounts.test.ts (1)

1184-1184: LGTM!

Also applies to: 1199-1205


Walkthrough

parseRateLimitReason in src/plugin/accounts.ts gains two new detection paths: a switch case that maps the explicit reason string "INSUFFICIENT_G1_CREDITS_BALANCE" to "QUOTA_EXHAUSTED", and an early message-text scan that matches the substrings "insufficient_g1_credits_balance" or "g1 credits balance" and returns "QUOTA_EXHAUSTED" before the existing capacity/rate-limit/quota checks. Two corresponding test assertions are added in src/plugin/accounts.test.ts: one for the direct reason code and one for a JSON-embedded reason in the message body with a 429 status.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix: classify G1 credit exhaustion as quota' directly and clearly summarizes the main change in the PR—mapping G1 credit exhaustion to QUOTA_EXHAUSTED classification.
Description check ✅ Passed The description is directly related to the changeset, explaining the classification of INSUFFICIENT_G1_CREDITS_BALANCE as QUOTA_EXHAUSTED, detection in JSON error messages, test coverage, and validation results.
Linked Issues check ✅ Passed The PR meets all requirements from issue #590: it maps INSUFFICIENT_G1_CREDITS_BALANCE to QUOTA_EXHAUSTED, detects the reason in error messages, includes regression test coverage, and provides validation confirmation.
Out of Scope Changes check ✅ Passed All changes are directly related to the stated objective of classifying G1 credit exhaustion as quota; no out-of-scope modifications are present in the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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.

@greptile-apps

greptile-apps Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR maps the INSUFFICIENT_G1_CREDITS_BALANCE reason code to QUOTA_EXHAUSTED in both the explicit reason-switch and the fallback message-text scanner, with regression tests for both paths.

  • Adds case \"INSUFFICIENT_G1_CREDITS_BALANCE\" to the switch in parseRateLimitReason, correctly placed before the RATE_LIMIT_EXCEEDED and MODEL_CAPACITY_EXHAUSTED cases.
  • Inserts a message-text check (insufficient_g1_credits_balance or g1 credits balance) before the existing resource exhausted capacity check, preserving correct classification priority.
  • Provides test coverage for the reason-field path and the JSON-blob message path; the human-readable \"g1 credits balance\" substring branch is not exercised by any test.

Confidence Score: 4/5

Safe to merge; the classification logic is correct and the ordering of checks ensures G1 credit exhaustion is never mistakenly mapped to MODEL_CAPACITY_EXHAUSTED.

The new reason-switch case and message-scan branch both work correctly for the intended Gemini/Antigravity 429 payload. The only gap is that the human-readable "g1 credits balance" substring arm in the message scanner has no test, so a future change to that string could silently regress without a failing test to catch it.

src/plugin/accounts.test.ts — the "g1 credits balance" message branch in accounts.ts is not covered by any test case.

Important Files Changed

Filename Overview
src/plugin/accounts.ts Adds INSUFFICIENT_G1_CREDITS_BALANCE to the reason switch and adds a message-text substring check for the same reason appearing inside JSON blob messages; ordering is correct (G1 check precedes the capacity/resource-exhausted check).
src/plugin/accounts.test.ts Adds regression tests for the new G1 reason-field path and the JSON-blob message path; the human-readable "g1 credits balance" substring branch added in accounts.ts has no corresponding test.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[parseRateLimitReason called
reason, message, status] --> B{status 529 or 503?}
    B -->|Yes| C[MODEL_CAPACITY_EXHAUSTED]
    B -->|No| D{status 500?}
    D -->|Yes| E[SERVER_ERROR]
    D -->|No| F{reason present?}
    F -->|Yes| G{reason.toUpperCase}
    G -->|QUOTA_EXHAUSTED| H[QUOTA_EXHAUSTED]
    G -->|INSUFFICIENT_G1_CREDITS_BALANCE new case| H
    G -->|RATE_LIMIT_EXCEEDED| I[RATE_LIMIT_EXCEEDED]
    G -->|MODEL_CAPACITY_EXHAUSTED| C
    G -->|no match| J
    F -->|No| J{message present?}
    J -->|Yes| K{includes insufficient_g1_credits_balance or g1 credits balance? new}
    K -->|Yes| H
    K -->|No| L{includes capacity / overloaded / resource exhausted?}
    L -->|Yes| C
    L -->|No| M{includes per minute / rate limit / too many requests?}
    M -->|Yes| I
    M -->|No| N{includes exhausted / quota?}
    N -->|Yes| H
    N -->|No| O{status 429?}
    J -->|No| O
    O -->|Yes| P[UNKNOWN]
    O -->|No| P
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[parseRateLimitReason called
reason, message, status] --> B{status 529 or 503?}
    B -->|Yes| C[MODEL_CAPACITY_EXHAUSTED]
    B -->|No| D{status 500?}
    D -->|Yes| E[SERVER_ERROR]
    D -->|No| F{reason present?}
    F -->|Yes| G{reason.toUpperCase}
    G -->|QUOTA_EXHAUSTED| H[QUOTA_EXHAUSTED]
    G -->|INSUFFICIENT_G1_CREDITS_BALANCE new case| H
    G -->|RATE_LIMIT_EXCEEDED| I[RATE_LIMIT_EXCEEDED]
    G -->|MODEL_CAPACITY_EXHAUSTED| C
    G -->|no match| J
    F -->|No| J{message present?}
    J -->|Yes| K{includes insufficient_g1_credits_balance or g1 credits balance? new}
    K -->|Yes| H
    K -->|No| L{includes capacity / overloaded / resource exhausted?}
    L -->|Yes| C
    L -->|No| M{includes per minute / rate limit / too many requests?}
    M -->|Yes| I
    M -->|No| N{includes exhausted / quota?}
    N -->|Yes| H
    N -->|No| O{status 429?}
    J -->|No| O
    O -->|Yes| P[UNKNOWN]
    O -->|No| P
Loading
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
src/plugin/accounts.ts:71-73
**Untested branch: `"g1 credits balance"` substring**

The `|| lower.includes("g1 credits balance")` arm is never exercised by any test. The new test only exercises the `"insufficient_g1_credits_balance"` arm (because the JSON payload is lowercased as `…"reason":"insufficient_g1_credits_balance"…`). A message like `"Your G1 credits balance is insufficient"` would hit the human-readable branch, but if that format ever diverges from expectations there's no safety net to catch a regression.

Reviews (1): Last reviewed commit: "fix: classify G1 credit exhaustion as qu..." | Re-trigger Greptile

Comment thread src/plugin/accounts.ts
Comment on lines +71 to +73
if (lower.includes("insufficient_g1_credits_balance") || lower.includes("g1 credits balance")) {
return "QUOTA_EXHAUSTED";
}

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.

P2 Untested branch: "g1 credits balance" substring

The || lower.includes("g1 credits balance") arm is never exercised by any test. The new test only exercises the "insufficient_g1_credits_balance" arm (because the JSON payload is lowercased as …"reason":"insufficient_g1_credits_balance"…). A message like "Your G1 credits balance is insufficient" would hit the human-readable branch, but if that format ever diverges from expectations there's no safety net to catch a regression.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/plugin/accounts.ts
Line: 71-73

Comment:
**Untested branch: `"g1 credits balance"` substring**

The `|| lower.includes("g1 credits balance")` arm is never exercised by any test. The new test only exercises the `"insufficient_g1_credits_balance"` arm (because the JSON payload is lowercased as `…"reason":"insufficient_g1_credits_balance"…`). A message like `"Your G1 credits balance is insufficient"` would hit the human-readable branch, but if that format ever diverges from expectations there's no safety net to catch a regression.

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Classify G1 credit exhaustion as quota exhaustion

1 participant