{"record":{"id":"0f902436a3912666","repo":"googleworkspace/cli","slug":"failed-to-fetch-message-e","errorCode":null,"errorMessage":"Failed to fetch message: {e}","messagePattern":"Failed to fetch message: (.+?)","errorType":"exception","errorClass":"GwsError","httpStatus":null,"severity":"error","filePath":"crates/google-workspace-cli/src/helpers/gmail/mod.rs","lineNumber":384,"sourceCode":"\npub(super) async fn fetch_message_metadata(\n    client: &reqwest::Client,\n    token: &str,\n    message_id: &str,\n) -> Result<OriginalMessage, GwsError> {\n    let url = format!(\n        \"https://gmail.googleapis.com/gmail/v1/users/me/messages/{}\",\n        crate::validate::encode_path_segment(message_id)\n    );\n\n    let resp = crate::client::send_with_retry(|| {\n        client\n            .get(&url)\n            .bearer_auth(token)\n            .query(&[(\"format\", \"full\")])\n    })\n    .await\n    .map_err(|e| GwsError::Other(anyhow::anyhow!(\"Failed to fetch message: {e}\")))?;\n\n    if !resp.status().is_success() {\n        let status = resp.status().as_u16();\n        let body = resp\n            .text()\n            .await\n            .unwrap_or_else(|_| \"(error body unreadable)\".to_string());\n        return Err(build_api_error(\n            status,\n            &body,\n            &format!(\"Failed to fetch message {message_id}\"),\n        ));\n    }\n\n    let msg: Value = resp\n        .json()\n        .await\n        .map_err(|e| GwsError::Other(anyhow::anyhow!(\"Failed to parse message: {e}\")))?;","sourceCodeStart":366,"sourceCodeEnd":402,"githubUrl":"https://github.com/googleworkspace/cli/blob/a3768d0e82ad83cca2da97724e46bea4ff0e6dbd/crates/google-workspace-cli/src/helpers/gmail/mod.rs#L366-L402","documentation":"The transport-level failure branch of `fetch_original_message`: `crate::client::send_with_retry` (which already retries transient errors) ultimately failed while GETting `https://gmail.googleapis.com/gmail/v1/users/me/messages/{id}?format=full`. This is a reqwest error after retries were exhausted — HTTP status errors are handled separately via `build_api_error`.","triggerScenarios":"No network / DNS failure to gmail.googleapis.com; TLS interception proxy rejecting the request; token present but connection dropped mid-body repeatedly so all retry attempts fail; extremely large message bodies timing out on every attempt.","commonSituations":"Running `gws gmail +reply`/`+forward` offline or behind a corporate proxy; flaky tethered connections; CI runners with blocked egress to googleapis.com.","solutions":["Confirm reachability: `curl -sS -o /dev/null -w '%{http_code}' https://gmail.googleapis.com/`.","Check proxy env vars (HTTPS_PROXY/ALL_PROXY) — reqwest honors them; exempt or fix googleapis.com.","Retry the command once the network is stable; the helper is stateless and safe to re-run.","If it persists, enable logging (`GOOGLE_WORKSPACE_CLI_LOG=gws=debug`) to see the underlying reqwest cause."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Cheap connectivity check before a reply/forward flow that must fetch the message\nif std::net::TcpStream::connect(\"gmail.googleapis.com:443\").is_err() {\n    eprintln!(\"gmail.googleapis.com unreachable — check network before replying\");\n}","typeGuard":null,"tryCatchPattern":"// Distinguish transport failure (retry) from API errors (surface):\nmatch fetch_original_message(client, token, id).await {\n    Err(GwsError::Other(e)) if e.to_string().starts_with(\"Failed to fetch message\") => retry_with_backoff(id).await,\n    Err(e) => return Err(e),\n    Ok(m) => m,\n}","preventionTips":["send_with_retry already retries — wrap caller-side retries with backoff so you do not hammer a dead network.","Keep googleapis.com domains reachable (proxy allowlist) in CI and corporate environments.","Treat this error as environmental (network), not auth — auth failures come back as GwsError::Api."],"tags":["gmail","network","reqwest","retry-exhausted","messages-api"],"backgroundTag":"http-request-failed","analyzedSha":"a3768d0e82ad83cca2da97724e46bea4ff0e6dbd","analyzedAt":"2026-08-16T19:51:46.516Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}