Summary
A Google Antigravity OAuth account can be fully valid for token refresh and inference, yet v1internal:retrieveUserQuotaSummary returns HTTP 403 when OpenCodex sends the current IDE fingerprint. The exact same bearer + project succeeds when the quota-summary request is retried once with the legacy Antigravity client family (User-Agent: antigravity/1.0).
This is account-specific: in a five-account pool, four accounts returned quota normally while one account consistently surfaced quotaUnavailable=true / access_denied. That failing account refreshed OAuth successfully and persisted the rotated credential, so the failure was not stale auth.
Reproduction
- Configure a multi-account
google-antigravity OAuth pool.
- Force per-account quota refresh.
- On the affected account, the first fixed-destination
retrieveUserQuotaSummary request with the IDE UA returns 403.
- Retry the same summary endpoint once with
antigravity/1.0, keeping the same bearer and project.
- The request returns the normal quota summary.
In live validation the compatibility retry restored all four expected windows (Gem, Gem weekly, Claude, Claude weekly). After the fix the same five-account production roster reports 5/5 quota rows available, 0 unavailable.
Proposed behavior
- On 403 only from the canonical
retrieveUserQuotaSummary endpoint, cancel the first body and retry that exact endpoint once with User-Agent: antigravity/1.0.
- Keep the current IDE fingerprint for inference/model discovery; the compatibility fingerprint is quota-accounting-only.
- Do not retry 401: it remains an authentication failure.
- Preserve the existing fixed-destination / redirect / SSRF protections.
Validation
- Focused upstream-dev quota suites after applying the patch: 237 pass / 0 fail / 990 assertions.
bun x tsc --noEmit: PASS.
- Live production validation: five stored AntiGravity OAuth accounts, 5/5 with quota, including the previously failing account.
No credentials, raw account identifiers, or private upstream payloads are included.
Summary
A Google Antigravity OAuth account can be fully valid for token refresh and inference, yet
v1internal:retrieveUserQuotaSummaryreturns HTTP 403 when OpenCodex sends the current IDE fingerprint. The exact same bearer + project succeeds when the quota-summary request is retried once with the legacy Antigravity client family (User-Agent: antigravity/1.0).This is account-specific: in a five-account pool, four accounts returned quota normally while one account consistently surfaced
quotaUnavailable=true/access_denied. That failing account refreshed OAuth successfully and persisted the rotated credential, so the failure was not stale auth.Reproduction
google-antigravityOAuth pool.retrieveUserQuotaSummaryrequest with the IDE UA returns 403.antigravity/1.0, keeping the same bearer and project.In live validation the compatibility retry restored all four expected windows (Gem, Gem weekly, Claude, Claude weekly). After the fix the same five-account production roster reports 5/5 quota rows available, 0 unavailable.
Proposed behavior
retrieveUserQuotaSummaryendpoint, cancel the first body and retry that exact endpoint once withUser-Agent: antigravity/1.0.Validation
bun x tsc --noEmit: PASS.No credentials, raw account identifiers, or private upstream payloads are included.