{"record":{"id":"4d7abcc071f68755","repo":"zeroclaw-labs/zeroclaw","slug":"xai-device-code-polling-failed-status-text","errorCode":null,"errorMessage":"xAI device-code polling failed ({status}): {text}","messagePattern":"xAI device-code polling failed \\((.+?)\\): (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-providers/src/auth/xai_oauth.rs","lineNumber":317,"sourceCode":"        let text = response.text().await.unwrap_or_default();\n        if let Ok(err) = serde_json::from_str::<OAuthErrorResponse>(&text) {\n            match err.error.as_str() {\n                \"authorization_pending\" => continue,\n                \"slow_down\" => {\n                    interval_secs = interval_secs.saturating_add(5);\n                    continue;\n                }\n                \"access_denied\" | \"authorization_denied\" => {\n                    anyhow::bail!(\"xAI device-code authorization was denied\")\n                }\n                \"expired_token\" => anyhow::bail!(\"xAI device-code expired\"),\n                _ => anyhow::bail!(\n                    \"xAI device-code polling failed ({status}): {}\",\n                    err.error_description.unwrap_or(err.error)\n                ),\n            }\n        }\n        anyhow::bail!(\"xAI device-code polling failed ({status}): {text}\");\n    }\n}\n\nasync fn parse_token_response(response: reqwest::Response) -> Result<TokenSet> {\n    let status = response.status();\n    let body = response.text().await.unwrap_or_default();\n    if !status.is_success() {\n        if let Ok(err) = serde_json::from_str::<OAuthErrorResponse>(&body) {\n            anyhow::bail!(\n                \"xAI OAuth token request failed ({status}): {}\",\n                err.error_description.unwrap_or(err.error)\n            );\n        }\n        anyhow::bail!(\"xAI OAuth token request failed ({status}): {body}\");\n    }\n\n    let parsed: TokenResponse =\n        serde_json::from_str(&body).context(\"Failed to parse xAI OAuth token response\")?;","sourceCodeStart":299,"sourceCodeEnd":335,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-providers/src/auth/xai_oauth.rs#L299-L335","documentation":"Fallback inside `poll_device_code_tokens`: the token endpoint returned non-2xx and the body did not parse as a `{error, error_description}` JSON document, so the raw body text is embedded with the status. This shape points at infrastructure (proxies, gateways, provider incidents) rather than OAuth semantics.","triggerScenarios":"5xx from xAI or an intermediary; an HTML error page from a proxy or captive portal; truncated or oversized bodies that fail JSON parsing.","commonSituations":"Corporate TLS-inspecting proxies rewriting responses; provider incidents; flaky egress paths.","solutions":["Retry with backoff — transient 5xx and proxy errors dominate this path","If the embedded text is HTML, identify the intercepting appliance and exempt auth.x.ai","Compare a direct `curl` to the token endpoint from the same host to isolate the middleman"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"match poll_device_code_tokens(&client, &ep, &device).await {\n    Ok(t) => t,\n    Err(e) if e.to_string().contains(\"xAI device-code polling failed\") && !has_oauth_error_code(&e) => {\n        retry_with_backoff(poll_device_code_tokens(&client, &ep, &device)).await? // HTML/5xx: transient path\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Exempt auth.x.ai from TLS-inspecting proxies","Retry with jitter — non-JSON error bodies are usually intermediary pages","Capture status and embedded body for diagnostics before retrying"],"tags":["oauth","xai","device-code","polling","proxy","http","rust"],"backgroundTag":"oauth-device-code-polling-failed","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}