zeroclaw-labs/zeroclaw · error · anyhow::Error
xAI OAuth callback missing code parameter
Error message
xAI OAuth callback missing code parameter
What it means
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.
Source
Thrown at crates/zeroclaw-providers/src/auth/xai_oauth.rs:428
anyhow::bail!("{err}: {desc}");
}
if let Some(expected) = expected_state {
let actual = params
.get("state")
.ok_or_else(|| anyhow::Error::msg("xAI OAuth callback missing state parameter"))?;
if actual != expected {
anyhow::bail!("xAI OAuth state mismatch");
}
}
if let Some(code) = params.get("code")
&& !code.trim().is_empty()
{
return Ok(code.trim().to_string());
}
if expected_state.is_none() && !trimmed.contains('=') && !trimmed.contains('?') {
return Ok(trimmed.to_string());
}
anyhow::bail!("xAI OAuth callback missing code parameter")
}
pub fn extract_account_id_from_jwt(token: &str) -> Option<String> {
let payload = decode_jwt_payload(token)?;
payload
.get("email")
.or_else(|| payload.get("sub"))
.and_then(serde_json::Value::as_str)
.map(ToString::to_string)
}
pub async fn import_grok_auth_profile(
auth_service: &super::AuthService,
profile: &str,
import_path: &std::path::Path,
) -> Result<()> {
::zeroclaw_log::scope!(
model_provider_type: "xai",View on GitHub (pinned to 88bb9c8533)
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
Defensive patterns
Strategy: validation
Validate before calling
// Before accepting a redirect, confirm it actually carries a code
let query = path.split_once('?').map_or(path, |(_, q)| q);
let params = parse_query_params(query);
let has_code = params
.get("code")
.is_some_and(|c| !c.trim().is_empty());
if !has_code {
// ignore this callback and keep listening for the real one
continue;
} Try / catch
match receive_loopback_code(&state, timeout).await {
Ok(code) => { /* proceed to token exchange */ }
Err(e) if e.to_string().contains("missing code parameter") => {
// user-facing: "authorization did not complete, retry login"
}
Err(e) => return Err(e),
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- No OAuth code provided
- Could not parse OAuth code from input
- xAI auth profile is not OAuth-based: {profile_id}
- xAI auth profile is missing token set: {profile_id}
- xAI token refresh is in backoff for {remaining}s due to prev
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/28dcab63a414fb00.
Report an issue: GitHub.