{"record":{"id":"1431e4e31954b3af","repo":"zed-industries/zed","slug":"e-x-ai-subscribed","errorCode":null,"errorMessage":"{e}","messagePattern":"\\{e\\}","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/x_ai_subscribed/src/x_ai_subscribed.rs","lineNumber":601,"sourceCode":"    http_client: &Arc<dyn HttpClient>,\n    cx: &mut AsyncApp,\n) -> Result<SuperGrokCredentials, LanguageModelCompletionError> {\n    let (creds, existing_task) = state\n        .read_with(&*cx, |s, _| (s.credentials.clone(), s.refresh_task.clone()))\n        .map_err(LanguageModelCompletionError::Other)?;\n\n    let creds = creds.ok_or(LanguageModelCompletionError::NoApiKey {\n        provider: PROVIDER_NAME,\n    })?;\n\n    if !creds.is_expired() {\n        return Ok(creds);\n    }\n\n    if let Some(shared_task) = existing_task {\n        return shared_task\n            .await\n            .map_err(|e| LanguageModelCompletionError::Other(anyhow!(\"{e}\")));\n    }\n\n    let http_client_clone = http_client.clone();\n    let state_clone = state.clone();\n    let previous_refresh_token = creds.refresh_token.clone();\n    let previous_email = creds.email.clone();\n\n    let generation = state\n        .read_with(&*cx, |s, _| s.auth_generation)\n        .map_err(LanguageModelCompletionError::Other)?;\n\n    let shared_task = cx\n        .spawn(async move |cx| {\n            let result = refresh_token(&http_client_clone, &previous_refresh_token).await;\n\n            match result {\n                Ok(tokens) => {\n                    let persist_result: Result<SuperGrokCredentials, Arc<anyhow::Error>> = async {","sourceCodeStart":583,"sourceCodeEnd":619,"githubUrl":"https://github.com/zed-industries/zed/blob/916fc2b8cb3a815cbef4a3b40e13081be72036b6/crates/x_ai_subscribed/src/x_ai_subscribed.rs#L583-L619","documentation":"This error wraps the failure of an already-in-flight shared token-refresh task. When an access token is expired and another task is already refreshing the SuperGrok credentials, get_fresh_credentials awaits that shared task instead of starting a second refresh; if the shared refresh fails (fatally, e.g. revoked refresh token, or transiently, e.g. network error), its Arc<anyhow::Error> is converted into LanguageModelCompletionError::Other via anyhow!(\"{e}\"). It exists so concurrent requesters don't each hit the token endpoint; they instead receive the original refresh failure.","triggerScenarios":"Calling stream_open_ai_completion while the stored SuperGrok access token is expired AND s.refresh_task is Some (another caller already started a refresh), and that shared refresh task completes with an Err — either RefreshError::Fatal (refresh token rejected/invalid_grant) or RefreshError::Transient (HTTP/network failure against the token endpoint).","commonSituations":"User's refresh token expired or was revoked server-side; corporate proxy or offline network blocks the OAuth token endpoint; the token server returns 4xx/5xx during a burst of completion requests after the access token lapsed.","solutions":["Read last_auth_error on the State entity (set on fatal refresh) and prompt the user to sign in again if the failure was fatal.","Inspect the wrapped Arc<anyhow::Error> to distinguish transient (retry after backoff) from fatal (re-authentication required) failures.","Retry the request after a short delay if the underlying failure was transient — a subsequent get_fresh_credentials will start a fresh refresh since refresh_task is cleared.","Check network/proxy configuration if failures cluster in restricted environments."],"exampleFix":"// before\nlet creds = get_fresh_credentials(&state, &http_client, cx).await?;\n// after\nlet creds = match get_fresh_credentials(&state, &http_client, cx).await {\n    Ok(creds) => creds,\n    Err(LanguageModelCompletionError::Other(e)) if is_transient(&e) => {\n        backoff_retry(|| get_fresh_credentials(&state, &http_client, cx)).await?\n    }\n    Err(e) => {\n        prompt_reauthentication();\n        return Err(e);\n    }\n};","handlingStrategy":"retry","validationCode":"let state_ref = state.upgrade().ok_or_else(|| anyhow!(\"state dropped\"))?;\nlet (creds, refresh_in_flight) = state_ref.read_with(&*cx, |s, _| (s.credentials.clone(), s.refresh_task.is_some()))?;\nif creds.as_ref().map_or(true, |c| c.is_expired()) && refresh_in_flight {\n    log::info!(\"token refresh already running; failure will surface as Other error\");\n}","typeGuard":"fn is_refresh_failure(err: &LanguageModelCompletionError) -> Option<&anyhow::Error> {\n    match err {\n        LanguageModelCompletionError::Other(e) => Some(e),\n        _ => None,\n    }\n}","tryCatchPattern":"match get_fresh_credentials(&state, &http_client, cx).await {\n    Ok(creds) => creds,\n    Err(LanguageModelCompletionError::Other(e)) => {\n        log::warn!(\"shared token refresh failed: {e:#}\");\n        return Err(anyhow!(\"SuperGrok auth refresh failed: {e:#}\"));\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Check last_auth_error before issuing completion requests after a period of idleness","Distinguish fatal vs transient refresh failures before deciding to retry","Add exponential backoff on transient token-endpoint failures","Monitor network reachability to the OAuth token endpoint in restricted environments"],"tags":["oauth","token-refresh","network","async"],"backgroundTag":"oauth-token-exchange-failed","analyzedSha":"916fc2b8cb3a815cbef4a3b40e13081be72036b6","analyzedAt":"2026-09-19T19:09:50.599Z","contentChangedAt":"2026-09-19T19:09:50.599Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}