googleworkspace/cli · error · GwsError

Failed to fetch user profile: {e}

Error message

Failed to fetch user profile: {e}

What it means

Transport failure in `fetch_user_email` (reply.rs): `send_with_retry` could not complete `GET https://gmail.googleapis.com/gmail/v1/users/me/profile`, which `+reply-all` uses for self-dedup of recipients and self-reply detection. HTTP failures (401/403) go through `build_api_error`; this branch means no HTTP response at all after retries.

Source

Thrown at crates/google-workspace-cli/src/helpers/gmail/reply.rs:184

    pub extra_to: Option<Vec<Mailbox>>,
    pub cc: Option<Vec<Mailbox>>,
    pub bcc: Option<Vec<Mailbox>>,
    pub remove: Option<Vec<Mailbox>>,
    pub html: bool,
    pub attachments: Vec<Attachment>,
}

/// Fetch the authenticated user's primary email from the Gmail profile API.
/// Used in reply-all for self-dedup (excluding the user from recipients) and
/// self-reply detection (switching to original-To-based addressing).
async fn fetch_user_email(client: &reqwest::Client, token: &str) -> Result<String, GwsError> {
    let resp = crate::client::send_with_retry(|| {
        client
            .get("https://gmail.googleapis.com/gmail/v1/users/me/profile")
            .bearer_auth(token)
    })
    .await
    .map_err(|e| GwsError::Other(anyhow::anyhow!("Failed to fetch user profile: {e}")))?;

    if !resp.status().is_success() {
        let status = resp.status().as_u16();
        let body = resp
            .text()
            .await
            .unwrap_or_else(|_| "(error body unreadable)".to_string());
        return Err(super::build_api_error(
            status,
            &body,
            "Failed to fetch user profile",
        ));
    }

    let profile: Value = resp
        .json()
        .await
        .map_err(|e| GwsError::Other(anyhow::anyhow!("Failed to parse profile: {e}")))?;

View on GitHub (pinned to a3768d0e82)

Solutions

  1. Restore connectivity and re-run the reply — no mail is sent until the final send call, so retry is safe.
  2. Verify `curl https://gmail.googleapis.com/` connects from the same shell (proxy env vars included).
  3. If behind an allowlisted firewall, keep gmail.googleapis.com on the list.
  4. Enable debug logs to see the underlying reqwest error kind.
Defensive patterns

Strategy: retry

Try / catch

// fetch_user_email only fails fatally at transport level; retry with backoff before giving up on reply-all
let email = match fetch_user_email(client, token).await {
    Ok(e) => e,
    Err(GwsError::Other(e)) if e.to_string().contains("Failed to fetch user profile") => {
        tokio::time::sleep(Duration::from_secs(2)).await;
        fetch_user_email(client, token).await?
    }
    Err(e) => return Err(e),
};

Prevention

When it happens

Trigger: Running `gws gmail +reply-all` offline; DNS/proxy failure to gmail.googleapis.com; connection resets persisting across the whole retry budget.

Common situations: Same network-class issues as other gmail helper calls, but noticed specifically during reply-all because that is the only flow that fetches the profile.

Related errors


AI-assisted analysis of googleworkspace/cli@a3768d0e82 (2026-08-16). Data as JSON: /api/errors/5497cd21cdc6ea9e. Report an issue: GitHub.