zeroclaw-labs/zeroclaw · error
Could not parse OAuth code from input
Error message
Could not parse OAuth code from input
What it means
parse_code_from_redirect could not interpret its input at all: there is no code query parameter, and the input fails the raw-code heuristic (length > 10, no spaces, no '&'). This is the terminal failure after both parsing strategies are exhausted, meaning the user pasted something that is neither a callback URL nor a plausible authorization code.
Source
Thrown at crates/zeroclaw-providers/src/auth/gemini_oauth.rs:521
// If we have code param, extract it
if let Some(code) = params.get("code") {
// Validate state if expected
if let Some(expected) = expected_state
&& let Some(actual) = params.get("state")
&& actual != expected
{
anyhow::bail!("OAuth state mismatch: expected {expected}, got {actual}");
}
return Ok(code.clone());
}
// Otherwise, assume it's the raw code (if long enough and no spaces)
if trimmed.len() > 10 && !trimmed.contains(' ') && !trimmed.contains('&') {
return Ok(trimmed.to_string());
}
anyhow::bail!("Could not parse OAuth code from input")
}
/// Extract account email from Google ID token.
pub fn extract_account_email_from_id_token(id_token: &str) -> Option<String> {
let parts: Vec<&str> = id_token.split('.').collect();
if parts.len() != 3 {
return None;
}
let payload = base64::engine::general_purpose::URL_SAFE_NO_PAD
.decode(parts[1])
.ok()?;
#[derive(Deserialize)]
struct IdTokenPayload {
email: Option<String>,
}
View on GitHub (pinned to 88bb9c8533)
Solutions
- Go back to the authorize URL, complete consent, and paste the final callback URL that contains code=...
- If the URL contains error=access_denied instead of code, the consent was denied — restart the login and click Allow
- Paste just the raw authorization code (a long single token like 4/0AcvDM...) with no spaces or extra text
Defensive patterns
Strategy: validation
Validate before calling
let t = input.trim();
let looks_like_url_with_code = t.contains("code=");
let looks_like_raw_code = t.len() > 10 && !t.contains(' ') && !t.contains('&');
anyhow::ensure!(
looks_like_url_with_code || looks_like_raw_code,
"input is neither a callback URL with code= nor a raw code; re-copy from the browser"
); Try / catch
match parse_code_from_redirect(input, expected_state) {
Ok(code) => code,
Err(e) if e.to_string() == "Could not parse OAuth code from input" => {
eprintln!("paste the full callback URL (it must contain code=...) or just the long code value");
return Err(e);
}
Err(e) => return Err(e),
} Prevention
- Copy the final browser URL after consent, not the consent page URL
- A raw code must be one long token: no spaces, no '&', longer than 10 characters
- If the URL shows error=..., fix the consent problem instead of re-pasting
When it happens
Trigger: Pasting a consent-error URL such as http://localhost:1456/auth/callback?error=access_denied (has no code param), a natural-language sentence (contains spaces), or a short fragment under 11 characters; also pasting a URL whose query string was mangled so code= is lost.
Common situations: Google redirected with an error instead of a code (access denied, app unverified) and the user pastes that URL; clipboard contains the wrong text; user pastes the verification user_code from the device flow instead of the authorization code.
Related errors
- No OAuth code provided
- Missing OAuth code in callback
- xAI OAuth callback missing code parameter
- unknown {}: {other}
- Google device code request failed ({}): {}
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/9a5a1d656724ab22.
Report an issue: GitHub.