googleworkspace/cli · error · GwsError
People API request failed: {e}
Error message
People API request failed: {e} What it means
Transport failure in `fetch_profile_display_name`, which calls the People API (`GET https://people.googleapis.com/v1/people/me?personFields=names`) with the Gmail OAuth token to decorate the From display name. `send_with_retry` exhausted its attempts without an HTTP response. Non-2xx (e.g. missing `profile` scope) is a separate `build_api_error` branch.
Source
Thrown at crates/google-workspace-cli/src/helpers/gmail/mod.rs:655
}
Ok(result)
}
/// Fetch the authenticated user's display name from the People API.
/// Requires a token with the `profile` scope.
async fn fetch_profile_display_name(
client: &reqwest::Client,
token: &str,
) -> Result<Option<String>, GwsError> {
let resp = crate::client::send_with_retry(|| {
client
.get("https://people.googleapis.com/v1/people/me")
.query(&[("personFields", "names")])
.bearer_auth(token)
})
.await
.map_err(|e| GwsError::Other(anyhow::anyhow!("People API request failed: {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(build_api_error(status, &body, "People API request failed"));
}
let body: Value = resp.json().await.map_err(|e| {
GwsError::Other(anyhow::anyhow!("Failed to parse People API response: {e}"))
})?;
Ok(parse_profile_display_name(&body))
}
/// Extract the display name from a People API `people.get` response.View on GitHub (pinned to a3768d0e82)
Solutions
- Verify egress: `curl -sS https://people.googleapis.com/` must connect (404/400 is fine, TLS failure is not).
- Add people.googleapis.com to the proxy/firewall allowlist alongside gmail.googleapis.com.
- Retry after restoring connectivity — profile display name is optional decoration and the command re-runs cleanly.
- Check `GOOGLE_WORKSPACE_CLI_LOG=gws=debug` output to distinguish connect vs TLS vs DNS.
Defensive patterns
Strategy: retry
Validate before calling
// The People API is a hidden dependency of gmail compose helpers — preflight both hosts
for host in ["gmail.googleapis.com", "people.googleapis.com"] {
if std::net::TcpStream::connect((host, 443)).is_err() {
return Err(anyhow::anyhow!("{host} unreachable — gmail helpers need both"));
}
} Try / catch
match fetch_profile_display_name(client, token).await {
// None (no names) is a valid Ok — only Err(GwsError::Other) transport failures warrant retry
Err(GwsError::Other(e)) if network_transient(&e) => {
tokio::time::sleep(Duration::from_secs(2)).await;
fetch_profile_display_name(client, token).await
}
other => other,
} Prevention
- Allowlist people.googleapis.com alongside gmail.googleapis.com in firewalls/proxies.
- Note display-name lookup requires the `profile` scope — grant it during `gws auth login` to avoid the sibling Api error.
- Treat transport errors here as retryable decoration failures, not fatal compose blockers, in your own orchestration.
When it happens
Trigger: Composing/sending with `gws gmail` while offline; DNS/proxy failure specifically reachable for gmail.googleapis.com but not people.googleapis.com (split egress rules); TLS interception blocking people.googleapis.com.
Common situations: Firewall allowlists that include Gmail but forget people.googleapis.com — a very common cause since the People call is a hidden dependency of the gmail helpers; flaky mobile networks.
Related errors
- Failed to fetch message: {e}
- Failed to fetch sendAs settings: {e}
- Failed to fetch attachment: {e}
- Failed to fetch user profile: {e}
- Pub/Sub pull failed: {e}
AI-assisted analysis of googleworkspace/cli@a3768d0e82 (2026-08-16).
Data as JSON: /api/errors/816ada909c10e317.
Report an issue: GitHub.