jlcodes99/cockpit-tools · warning

刷新配额失败: {}

Error message

刷新配额失败: {}

What it means

After a Codex account re-authorization completes and the new tokens are saved, the app attempts to refresh the account's quota via codex_quota::refresh_freshly_authorized_account_quota. This error is logged (non-fatal) when that refresh call fails, meaning the account is usable but its quota snapshot may be stale.

Source

Thrown at src-tauri/src/commands/codex_account_commands.rs:1881

            Some(trimmed)
        }
    }) {
        codex_account::upsert_account_for_reauth(tokens, account_id)?
    } else {
        codex_account::upsert_account(tokens)?
    };

    // 旧官方客户端可能仍持有同一账号的旧 auth.json。普通新增授权使用刚落库的
    // 凭据直接查询配额,避免 live authority 把新 Token 覆盖回旧 Token;重新授权
    // 则等自动切号提交完成后再按正常流程刷新。
    if reauth_account_id.is_none() {
        if let Err(e) = codex_quota::refresh_freshly_authorized_account_quota(
            &account.id,
            account.token_generation,
        )
        .await
        {
            logger::log_error(&format!("刷新配额失败: {}", e));
        }
    }

    let loaded =
        codex_account::load_account(&account.id).ok_or_else(|| "账号保存后无法读取".to_string())?;
    if reauth_account_id.is_some() {
        if let Err(error) = codex_account::sync_bound_oauth_consumers_after_reauth(&loaded.id).await
        {
            logger::log_warn(&format!(
                "OAuth 重新授权后同步绑定消费者失败,保留已保存授权: account_id={}, error={}",
                loaded.id, error
            ));
        }
    }
    logger::log_info(&format!(
        "Codex OAuth 账号已保存: account_id={}, email={}",
        loaded.id, loaded.email
    ));

View on GitHub (pinned to 1ed8b77992)

Solutions

  1. Retry the quota refresh manually later — the account itself was saved successfully, only the quota snapshot failed
  2. Check network connectivity / proxy settings to the quota API endpoint
  3. Verify the account's token_generation in storage matches the one used for the refresh call
  4. Check logs for the wrapped error detail to see whether it was a 401 (token rejected) or a transport error

Example fix

// before
if let Err(e) = codex_quota::refresh_freshly_authorized_account_quota(&account.id, account.token_generation).await {
    logger::log_error(&format!("刷新配额失败: {}", e));
}
// after
if let Err(e) = codex_quota::refresh_freshly_authorized_account_quota(&account.id, account.token_generation).await {
    logger::log_error(&format!("刷新配额失败: {}", e));
    // schedule a bounded retry so the quota snapshot isn't left stale
    tokio::spawn(async move {
        tokio::time::sleep(std::time::Duration::from_secs(30)).await;
        let _ = codex_quota::refresh_freshly_authorized_account_quota(&account.id, account.token_generation).await;
    });
}
Defensive patterns

Strategy: retry

Validate before calling

// check connectivity to the quota endpoint before trusting the snapshot
if !is_online() {
    logger::log_warn("网络不可用,跳过配额刷新,配额数据可能过期");
}

Try / catch

// treat as non-fatal; the account is saved regardless
if let Err(e) = codex_quota::refresh_freshly_authorized_account_quota(&account.id, account.token_generation).await {
    logger::log_warn(&format!("刷新配额失败(账号已保存,可稍后重试): {}", e));
    schedule_quota_refresh_retry(&account.id, Duration::from_secs(30), /* max_attempts */ 3);
}

Prevention

When it happens

Trigger: The reauth flow saved new tokens, then refresh_freshly_authorized_account_quota(&account.id, token_generation) returned Err — e.g. upstream quota API rejected the fresh token, network failure, or token_generation mismatch.

Common situations: Upstream Codex quota endpoint temporarily unavailable or rate-limiting right after login; network proxy/firewall interference; the freshly issued token not yet propagated upstream (eventual consistency); stale token_generation value passed through.

Related errors


AI-assisted analysis of jlcodes99/cockpit-tools@1ed8b77992 (2026-09-05). Data as JSON: /api/errors/ccadf680664273f6. Report an issue: GitHub.