Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1608,6 +1608,46 @@ export const createAntigravityPlugin = (providerId: string) => async (
}
}

// Handle 403 VALIDATION_REQUIRED - account needs Google verification
// This prevents "Body already used" errors from SDK trying to parse the response twice
if (response.status === 403) {
const cloned403 = response.clone();
const body403 = await extractRetryInfoFromBody(cloned403);
Comment on lines +1614 to +1615
Copy link
Contributor

Choose a reason for hiding this comment

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

Redundant clone - extractRetryInfoFromBody already clones the response internally (line 538). Pass response directly.

Suggested change
const cloned403 = response.clone();
const body403 = await extractRetryInfoFromBody(cloned403);
const body403 = await extractRetryInfoFromBody(response);
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/plugin.ts
Line: 1614:1615

Comment:
Redundant clone - `extractRetryInfoFromBody` already clones the response internally (line 538). Pass `response` directly.

```suggestion
                  const body403 = await extractRetryInfoFromBody(response);
```

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


if (body403.reason === "VALIDATION_REQUIRED") {
const cooldownMs = 10 * 60 * 1000; // 10 minutes - give user time to verify
accountManager.markAccountCoolingDown(account, cooldownMs, "validation-required");
accountManager.markRateLimited(account, cooldownMs, family, headerStyle, model);

const accountLabel = account.email || `Account ${account.index + 1}`;
await showToast(
`${accountLabel} requires Google verification. Visit accounts.google.com to verify, then retry. Switching accounts...`,
"warning"
);
pushDebug(`validation-required: account=${account.index} cooldown=${cooldownMs}ms`);

// Record failure for health tracking
getHealthTracker().recordFailure(account.index);

// Force switch to another account
lastFailure = {
response,
streaming: prepared.streaming,
debugContext,
requestedModel: prepared.requestedModel,
projectId: prepared.projectId,
endpoint: prepared.endpoint,
effectiveModel: prepared.effectiveModel,
sessionId: prepared.sessionId,
toolDebugMissing: prepared.toolDebugMissing,
toolDebugSummary: prepared.toolDebugSummary,
toolDebugPayload: prepared.toolDebugPayload,
};
shouldSwitchAccount = true;
break;
}
}

// Success - reset rate limit backoff state for this quota
const quotaKey = headerStyleToQuotaKey(headerStyle, family);
resetRateLimitState(account.index, quotaKey);
Expand Down
11 changes: 10 additions & 1 deletion src/plugin/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,14 @@ export interface AccountStorage {
activeIndex: number;
}

export type CooldownReason = "auth-failure" | "network-error" | "project-error";
/**
* Reasons why an account may be cooling down.
* - "auth-failure": Authentication/token refresh failed
* - "network-error": Network connectivity issues
* - "project-error": Project ID resolution failed
* - "validation-required": Google requires account verification (403 PERMISSION_DENIED with VALIDATION_REQUIRED)
*/
export type CooldownReason = "auth-failure" | "network-error" | "project-error" | "validation-required";
Copy link
Contributor

Choose a reason for hiding this comment

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

The validation-required cooldown reason is added here, but the actual implementation in src/plugin.ts that handles 403 VALIDATION_REQUIRED errors is missing from this PR. According to the PR description, code needs to be added before line 1616 in plugin.ts to:

  1. Clone the 403 response
  2. Check for VALIDATION_REQUIRED reason
  3. Mark the account as cooling down
  4. Switch to another account

Without the plugin.ts changes, this type addition has no effect.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/plugin/storage.ts
Line: 183:183

Comment:
The `validation-required` cooldown reason is added here, but the actual implementation in `src/plugin.ts` that handles 403 VALIDATION_REQUIRED errors is missing from this PR. According to the PR description, code needs to be added before line 1616 in `plugin.ts` to:
1. Clone the 403 response
2. Check for VALIDATION_REQUIRED reason
3. Mark the account as cooling down
4. Switch to another account

Without the `plugin.ts` changes, this type addition has no effect.

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


export interface AccountMetadataV3 {
email?: string;
Expand All @@ -189,6 +196,8 @@ export interface AccountMetadataV3 {
cooldownReason?: CooldownReason;
/** Per-account device fingerprint for rate limit mitigation */
fingerprint?: import("./fingerprint").Fingerprint;
/** History of previous fingerprints for this account */
fingerprintHistory?: import("./fingerprint").FingerprintVersion[];
Copy link
Contributor

Choose a reason for hiding this comment

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

Verify that the FingerprintVersion type is exported from src/plugin/fingerprint.ts and is being used correctly by the fingerprintHistory consumers in src/plugin/accounts.ts. The type import looks correct, but verify that all existing fingerprint history code is compatible with this schema addition.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/plugin/storage.ts
Line: 200:200

Comment:
Verify that the `FingerprintVersion` type is exported from `src/plugin/fingerprint.ts` and is being used correctly by the `fingerprintHistory` consumers in `src/plugin/accounts.ts`. The type import looks correct, but verify that all existing fingerprint history code is compatible with this schema addition.

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

}

export interface AccountStorageV3 {
Expand Down