{"record":{"id":"58181cfddbf6c8c0","repo":"zeroclaw-labs/zeroclaw","slug":"no-xai-oauth-code-provided","errorCode":null,"errorMessage":"No xAI OAuth code provided","messagePattern":"No xAI OAuth code provided","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-providers/src/auth/xai_oauth.rs","lineNumber":401,"sourceCode":"        .split_whitespace()\n        .nth(1)\n        .ok_or_else(|| anyhow::Error::msg(\"xAI callback request missing path\"))?;\n    let code = parse_code_from_redirect(path, Some(expected_state))?;\n\n    let body = \"<html><body><h2>ZeroClaw xAI login complete</h2><p>You can close this tab.</p></body></html>\";\n    let response = format!(\n        \"HTTP/1.1 200 OK\\r\\nContent-Type: text/html; charset=utf-8\\r\\nContent-Length: {}\\r\\nConnection: close\\r\\n\\r\\n{}\",\n        body.len(),\n        body\n    );\n    let _ = stream.write_all(response.as_bytes()).await;\n    Ok(code)\n}\n\npub fn parse_code_from_redirect(input: &str, expected_state: Option<&str>) -> Result<String> {\n    let trimmed = input.trim();\n    if trimmed.is_empty() {\n        anyhow::bail!(\"No xAI OAuth code provided\");\n    }\n    let query = trimmed.split_once('?').map_or(trimmed, |(_, query)| query);\n    let params = parse_query_params(query);\n    if let Some(err) = params.get(\"error\") {\n        let desc = params\n            .get(\"error_description\")\n            .cloned()\n            .unwrap_or_else(|| \"xAI OAuth authorization failed\".to_string());\n        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    }","sourceCodeStart":383,"sourceCodeEnd":419,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-providers/src/auth/xai_oauth.rs#L383-L419","documentation":"`parse_code_from_redirect` (xAI) rejects empty or whitespace-only input before any parsing. The function accepts a full callback URL, a bare query string, or a raw code — but the trimmed input must be non-empty. This is the fail-fast guard for manual code entry paths.","triggerScenarios":"Passing an empty string or whitespace to `parse_code_from_redirect(input, expected_state)`; a user submits an empty prompt when the code is pasted manually; the feeding variable was never assigned.","commonSituations":"Manual paste flows where the user presses enter without pasting; a default-empty variable in the caller; clipboard read returning nothing.","solutions":["Trim the input and require non-empty before calling — fail fast with your own message","Re-prompt when the user submits nothing","Check the variable feeding the call is actually wired to the clipboard or prompt"],"exampleFix":"// before\nlet code = parse_code_from_redirect(&input, None)?; // \"No xAI OAuth code provided\" on empty input\n\n// after\nlet input = input.trim();\nif input.is_empty() {\n    anyhow::bail!(\"paste the code copied from the browser\");\n}\nlet code = parse_code_from_redirect(input, None)?;","handlingStrategy":"validation","validationCode":"let input = input.trim();\nif input.is_empty() {\n    anyhow::bail!(\"paste the code copied from the browser\");\n}\nlet code = parse_code_from_redirect(input, expected_state)?;","typeGuard":null,"tryCatchPattern":"match parse_code_from_redirect(&raw, expected_state) {\n    Ok(code) => code,\n    Err(e) if e.to_string().contains(\"No xAI OAuth code provided\") => reprompt_for_code().await,\n    Err(e) => return Err(e),\n}","preventionTips":["Trim input and require non-empty before calling — fail fast with your own message","Re-prompt on empty manual entry instead of propagating the parse error","Wire the input variable to the real source (prompt/clipboard), not a default"],"tags":["oauth","xai","input-validation","rust"],"backgroundTag":"missing-required-parameter","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}