jlcodes99/cockpit-tools · error

未获取到 Refresh Token。 可能原因:您之前已授权过此应用 解决方案: 1. 访问 https://my

Error message

未获取到 Refresh Token。

可能原因:您之前已授权过此应用

解决方案:
1. 访问 https://myaccount.google.com/permissions
2. 撤销 'Antigravity Tools' 的访问权限
3. 重新进行 OAuth 授权

What it means

Google does not return a refresh_token when the user has already previously granted consent to the OAuth app (unless prompt=consent / access_type=offline is forced). start_oauth_login requires a refresh_token for long-lived access, so when token_res.refresh_token is None it logs and returns this user-facing multi-line error explaining the cause and remedy.

Source

Thrown at src-tauri/src/commands/oauth.rs:69

    let token_res = modules::oauth_server::start_oauth_flow(app_handle.clone())
        .await
        .map_err(|e| {
            modules::logger::log_error(&format!("OAuth 流程失败: {}", e));
            e
        })?;

    modules::logger::log_info("OAuth 授权成功,检查 refresh_token...");

    let refresh_token = token_res.refresh_token.ok_or_else(|| {
        let msg = "未获取到 Refresh Token。\n\n\
         可能原因:您之前已授权过此应用\n\n\
         解决方案:\n\
         1. 访问 https://myaccount.google.com/permissions\n\
         2. 撤销 'Antigravity Tools' 的访问权限\n\
         3. 重新进行 OAuth 授权"
            .to_string();
        modules::logger::log_error(&msg);
        msg
    })?;

    modules::logger::log_info("获取用户信息...");
    let user_info = modules::oauth::get_user_info(&token_res.access_token)
        .await
        .map_err(|e| {
            modules::logger::log_error(&format!("获取用户信息失败: {}", e));
            e
        })?;

    modules::logger::log_info(&format!(
        "用户: {} ({})",
        user_info.email,
        user_info.name.as_deref().unwrap_or("无名称")
    ));

    let token_data = models::TokenData::new(

View on GitHub (pinned to 1ed8b77992)

Solutions

  1. Follow the message: visit https://myaccount.google.com/permissions, revoke 'Antigravity Tools' access, then redo the OAuth authorization to force a new refresh_token
  2. Fix the client so the authorization request includes access_type=offline and prompt=consent, guaranteeing a refresh_token on every flow
  3. Use a different Google account for a fresh consent if revocation is not feasible
  4. If the app supports it, use an existing stored account instead of re-running OAuth for the same Google account

Example fix

// before
let refresh_token = token_res.refresh_token.ok_or_else(|| {
    let msg = "未获取到 Refresh Token...".to_string();
    modules::logger::log_error(&msg);
    msg
})?;
// after
// client-side: force Google to re-issue a refresh_token every time
let auth_url = build_google_auth_url(&client_id, &redirect_uri,
    "access_type=offline&prompt=consent");
// ...
let refresh_token = token_res.refresh_token.ok_or_else(|| {
    let msg = "未获取到 Refresh Token...".to_string();
    modules::logger::log_error(&msg);
    msg
})?;
Defensive patterns

Strategy: try-catch

Validate before calling

// force refresh_token issuance on every authorization request
let auth_url = format!(
    "https://accounts.google.com/o/oauth2/v2/auth?client_id={}&redirect_uri={}&response_type=code&scope={}&access_type=offline&prompt=consent",
    client_id, urlencode(redirect_uri), urlencode(scopes)
);

Try / catch

let refresh_token = match token_res.refresh_token {
    Some(rt) => rt,
    None => {
        // recovery path: instruct user to revoke and re-consent, then retry automatically
        return Err("未获取到 Refresh Token:请访问 https://myaccount.google.com/permissions 撤销应用授权后重试".to_string());
    }
};

Prevention

When it happens

Trigger: token_res.refresh_token.ok_or_else(...) fires — i.e. the token exchange succeeded but Google omitted refresh_token because this Google account had previously authorized 'Antigravity Tools' and consent was not re-prompted.

Common situations: Re-adding an account that was authorized before; the app's OAuth request not forcing prompt=consent&access_type=offline; testing repeatedly with the same Google account; tokens revoked server-side but Google still skipping refresh_token issuance on silent re-consent.

Related errors


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