{"record":{"id":"fa03a4b42246f3d3","repo":"Hmbown/CodeWhale","slug":"xai-device-code-token-exchange-failed-detail","errorCode":null,"errorMessage":"xAI device-code token exchange failed: {detail}","messagePattern":"xAI device-code token exchange failed: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/xai_oauth.rs","lineNumber":1286,"sourceCode":"        (\"device_code\", device_code),\n    ];\n    #[cfg(test)]\n    crate::external_credentials::record_oauth_network();\n    let response = client\n        .post(token_endpoint)\n        .form(&params)\n        .send()\n        .context(\"xAI device-code token poll failed\")?;\n    let (status, body): (_, TokenResponse) =\n        parse_oauth_json_response(response, \"xAI device-code token exchange\")?;\n    if let Some(err) = body.error.as_deref() {\n        if matches!(err, \"authorization_pending\" | \"slow_down\") {\n            bail!(\"{err}\");\n        }\n        // Poll requests carry the device credential. Keep diagnostics to the\n        // standard error code and HTTP status rather than echoing descriptions.\n        let detail = oauth_failure_detail(Some(err), None, status);\n        bail!(\"xAI device-code token exchange failed: {detail}\");\n    }\n    if !status.is_success() {\n        let detail = oauth_failure_detail(None, None, status);\n        bail!(\"xAI device-code token exchange failed: {detail}\");\n    }\n    Ok(body)\n}\n\nfn jwt_expiry_seconds(token: &str) -> Option<u64> {\n    use base64::Engine as _;\n    use base64::engine::general_purpose::URL_SAFE_NO_PAD;\n    let mut parts = token.split('.');\n    let _header = parts.next()?;\n    let payload = parts.next()?;\n    let decoded = URL_SAFE_NO_PAD.decode(payload).ok()?;\n    let claims: Value = serde_json::from_slice(&decoded).ok()?;\n    claims.get(\"exp\")?.as_u64()\n}","sourceCodeStart":1268,"sourceCodeEnd":1304,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/xai_oauth.rs#L1268-L1304","documentation":"The device-code token poll reached the token endpoint but the exchange failed with a terminal OAuth error — that is, an error other than the transient authorization_pending or slow_down signals, which are retried internally. {detail} carries the redacted failure reason; the request carried the device credential, so details are deliberately limited.","triggerScenarios":"Thrown at crates/tui/src/xai_oauth.rs:1286 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Check {detail}: expired_token means the user took too long — restart device-code login","access_denied means the user or xAI rejected the request; confirm and retry login","Verify the client_id and device authorization are still valid, then restart the flow","Fall back to XAI_API_KEY if device-code login keeps failing"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}