jlcodes99/cockpit-tools · warning
${updatedAccount.quota_error.message}
Error message
${updatedAccount.quota_error.message} What it means
During a token-refresh flow in useAccountStore, the backend attaches a quota_error to the updated account. The store deliberately re-throws the backend-provided message after committing state, so the UI can render the account as failed (red X). The thrown message is dynamic — it is whatever string the backend put in quota_error.message (e.g. quota exhausted, rate limited, account suspended).
Source
Thrown at src/stores/useAccountStore.ts:413
currentTarget,
updatedAccount,
);
}
}
return {
currentAccount:
nextByTarget[target]?.id === accountId
? updatedAccount
: state.currentAccount?.id === accountId
? updatedAccount
: state.currentAccount,
currentAccountsByTarget: nextByTarget,
};
});
// 如果后端返回了配额错误信息,需要抛出异常让 UI 捕获并显示为失败(红叉)
if (updatedAccount.quota_error) {
throw new Error(updatedAccount.quota_error.message);
}
if (updatedAccount.quota?.is_forbidden) {
throw new Error("403 Forbidden");
}
} catch (e) {
// Token 级别失败(如 invalid_grant 会改变 disabled 状态):全量刷新确保数据正确
// 如果是我们自己 throw 的配额错误,因为状态已经局部更新,不再需要全量刷新
const isQuotaError = e instanceof Error && (
get().accounts.find(a => a.id === accountId)?.quota_error?.message === e.message ||
e.message === "403 Forbidden"
);
if (!isQuotaError) {
await get().fetchAccounts();
}
throw e;
} finally {
await get().fetchCurrentAccount(target);
}View on GitHub (pinned to 1ed8b77992)
Solutions
- Read the thrown message — it is the provider's own quota explanation and dictates the fix
- Wait for the quota window to reset or switch to a paid/higher-tier plan for that provider
- Disable or remove the affected account so it is not retried in rotation
- Check the account's quota.is_forbidden status; if forbidden, re-auth or replace the account
Defensive patterns
Strategy: try-catch
Validate before calling
if (updatedAccount.quota_error) {
console.warn(`Account ${updatedAccount.id} has quota error: ${updatedAccount.quota_error.message}`);
} Type guard
function hasQuotaError(a: { quota_error?: { message: string } | null }): a is { quota_error: { message: string } } {
return Boolean(a.quota_error?.message);
} Try / catch
try {
await refreshAccountToken(accountId);
} catch (e) {
markAccountFailed(accountId, e.message); // render red X with backend quota message
if (String(e.message) === '403 Forbidden') suggestReauth(accountId);
} Prevention
- Surface quota_error messages directly in the account list UI
- Monitor quota.is_forbidden and auto-disable forbidden accounts
- Rotate to backup accounts before quotas exhaust
- Catch token-level failures and trigger a full account refresh
When it happens
Trigger: Any refresh/switch operation on an account where the backend response's updatedAccount.quota_error is set — typically when the provider reports the account hit its quota or was rejected during quota check.
Common situations: Free-tier accounts exhausting daily quotas, provider returning 429/quota errors en masse, or an account flagged/suspended upstream; users see the red X with the backend's message text.
Related errors
- [AccountGroups] Failed to load groups: ${String(error)}
- 403 Forbidden
- CODEX_PENDING_OAUTH_ACCOUNT
- [TraeAutoCheckin] 保存自动签到日志失败:
- [WorkbuddyAutoCheckin] 本地缓存保存失败:
AI-assisted analysis of jlcodes99/cockpit-tools@1ed8b77992 (2026-09-05).
Data as JSON: /api/errors/c1cab20a218e1f8c.
Report an issue: GitHub.