{"record":{"id":"28dcab63a414fb00","repo":"zeroclaw-labs/zeroclaw","slug":"xai-oauth-callback-missing-code-parameter","errorCode":null,"errorMessage":"xAI OAuth callback missing code parameter","messagePattern":"xAI OAuth callback missing code parameter","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-providers/src/auth/xai_oauth.rs","lineNumber":428,"sourceCode":"        anyhow::bail!(\"{err}: {desc}\");\n    }\n    if let Some(expected) = expected_state {\n        let actual = params\n            .get(\"state\")\n            .ok_or_else(|| anyhow::Error::msg(\"xAI OAuth callback missing state parameter\"))?;\n        if actual != expected {\n            anyhow::bail!(\"xAI OAuth state mismatch\");\n        }\n    }\n    if let Some(code) = params.get(\"code\")\n        && !code.trim().is_empty()\n    {\n        return Ok(code.trim().to_string());\n    }\n    if expected_state.is_none() && !trimmed.contains('=') && !trimmed.contains('?') {\n        return Ok(trimmed.to_string());\n    }\n    anyhow::bail!(\"xAI OAuth callback missing code parameter\")\n}\n\npub fn extract_account_id_from_jwt(token: &str) -> Option<String> {\n    let payload = decode_jwt_payload(token)?;\n    payload\n        .get(\"email\")\n        .or_else(|| payload.get(\"sub\"))\n        .and_then(serde_json::Value::as_str)\n        .map(ToString::to_string)\n}\n\npub async fn import_grok_auth_profile(\n    auth_service: &super::AuthService,\n    profile: &str,\n    import_path: &std::path::Path,\n) -> Result<()> {\n    ::zeroclaw_log::scope!(\n        model_provider_type: \"xai\",","sourceCodeStart":410,"sourceCodeEnd":446,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-providers/src/auth/xai_oauth.rs#L410-L446","documentation":"Thrown by parse_code_from_redirect when an xAI OAuth redirect callback parses as a query string but contains no non-empty code parameter. The error and state checks already passed (or state was not expected), so the authorization server redirected back to 127.0.0.1:56121 without ever issuing an authorization code. The loopback listener accepts exactly one connection, so whatever request hit it first is the one parsed.","triggerScenarios":"receive_loopback_code_inner reads the first HTTP request on 127.0.0.1:56121 and extracts the path; if that path carries query parameters (contains '=' or '?') but no code=... entry, this fires. Happens when xAI redirects with only state=..., when the browser or an extension prefetches the callback URL before the real redirect, or when consent is abandoned mid-flow.","commonSituations":"User starts `zeroclaw` xAI OAuth login, denies or abandons the consent screen, and the browser still resolves the loopback redirect; browser prefetch or extensions hitting port 56121 first; a xAI-side change to the redirect query format.","solutions":["Retry the xAI OAuth login command to get a fresh state and code, and complete consent in the browser this time","Watch the callback URL in the browser address bar: if it lacks code=..., the consent step did not finish - confirm on the xAI page","Close extra tabs and disable prefetching extensions before retrying, so nothing touches port 56121 before the real redirect","If it persists, capture the exact redirect URL and verify xAI still appends code to the loopback redirect"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before accepting a redirect, confirm it actually carries a code\nlet query = path.split_once('?').map_or(path, |(_, q)| q);\nlet params = parse_query_params(query);\nlet has_code = params\n    .get(\"code\")\n    .is_some_and(|c| !c.trim().is_empty());\nif !has_code {\n    // ignore this callback and keep listening for the real one\n    continue;\n}","typeGuard":null,"tryCatchPattern":"match receive_loopback_code(&state, timeout).await {\n    Ok(code) => { /* proceed to token exchange */ }\n    Err(e) if e.to_string().contains(\"missing code parameter\") => {\n        // user-facing: \"authorization did not complete, retry login\"\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Keep the login terminal in the foreground so the loopback listener sees the real redirect first","Complete the xAI consent screen in one sitting; do not close the tab mid-flow","Close prefetching tabs and extensions before starting OAuth login","Treat a callback without code= as a non-event: keep listening instead of failing the whole flow"],"tags":["oauth","xai","authorization-code","loopback","rust"],"backgroundTag":"oauth-missing-authorization-code","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}