# Proxy account pool & auto-disable behavior ## What we wanted - Keep the proxy “always-on” even when some Google OAuth accounts become invalid. - Avoid repeatedly attempting to refresh a revoked `refresh_token` (noise + wasted requests). - Make failures actionable by surfacing account state clearly in the UI. ## What we got ### 1) Disabled accounts are skipped by the proxy pool Account files can be marked as disabled on disk (`accounts/.json`): - `disabled: true` - `disabled_at: ` - `disabled_reason: ` The proxy token pool loader skips such accounts: - `TokenManager::load_single_account(...)` in [`src-tauri/src/proxy/token_manager.rs`](../../src-tauri/src/proxy/token_manager.rs) ### 2) Automatic disable on OAuth `invalid_grant` If an account refresh fails with `invalid_grant` during token refresh, the proxy marks it disabled and removes it from the in-memory pool: - Refresh/disable logic: `TokenManager::get_token(...)` in [`src-tauri/src/proxy/token_manager.rs`](../../src-tauri/src/proxy/token_manager.rs) - Persist disable flags to disk: `TokenManager::disable_account(...)` in [`src-tauri/src/proxy/token_manager.rs`](../../src-tauri/src/proxy/token_manager.rs) This prevents endless rotation attempts against a dead account. ### 3) Batch quota refresh skips disabled accounts When refreshing quotas for all accounts, disabled ones are skipped immediately: - `refresh_all_quotas(...)` in [`src-tauri/src/commands/mod.rs`](../../src-tauri/src/commands/mod.rs) ### 4) UI surfaces disabled state and blocks actions The accounts UI reads `disabled` fields and shows a “Disabled” badge and tooltip, and disables “switch / refresh” controls: - Account type includes `disabled*` fields: [`src/types/account.ts`](../../src/types/account.ts) - Card view: [`src/components/accounts/AccountCard.tsx`](../../src/components/accounts/AccountCard.tsx) - Table row view: [`src/components/accounts/AccountRow.tsx`](../../src/components/accounts/AccountRow.tsx) - Filters: “Available” excludes disabled accounts: [`src/pages/Accounts.tsx`](../../src/pages/Accounts.tsx) Translations: - [`src/locales/en.json`](../../src/locales/en.json) - [`src/locales/zh.json`](../../src/locales/zh.json) ### 5) API errors avoid leaking user emails Token refresh failures returned to API clients no longer include account emails: - Error message construction: `TokenManager::get_token(...)` in [`src-tauri/src/proxy/token_manager.rs`](../../src-tauri/src/proxy/token_manager.rs) - Proxy error mapping: `handle_messages(...)` in [`src-tauri/src/proxy/handlers/claude.rs`](../../src-tauri/src/proxy/handlers/claude.rs) ## Operational guidance - If an account becomes disabled due to `invalid_grant`, it usually means the `refresh_token` was revoked or expired. - Re-authorize the account (or update the stored token) to restore it. ## Validation 1) Ensure at least one account file has `disabled: true`. 2) Start the proxy and verify: - The disabled account is not selected for requests. - Batch quota refresh logs show “Skipping … (Disabled)”. - The UI shows the Disabled badge and blocks actions.