Kuberwastaken/claurst · error · anyhow::Error
OAuth error
Error message
OAuth error: {} What it means
The OAuth provider redirected back with an `error` query parameter instead of an authorization code — the user denied consent, or the provider rejected the request (e.g. invalid_client, access_denied, temporarily_unavailable). The formatted value is the provider's error code.
Solutions
- Read the error code: access_denied means the user cancelled; restart the flow if they want to proceed
- For server/provider errors, wait and retry the login
- Verify the client_id and scopes in the auth URL are still registered with the provider
Defensive patterns
Strategy: fallback
When it happens
Trigger: Thrown at src-rust/crates/cli/src/codex_oauth_flow.rs:174 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of Kuberwastaken/claurst@b0637c97ec (2026-09-10).
Data as JSON: /api/errors/96319bbcab5d1372.
Report an issue: GitHub.
Appendix: source
Thrown at src-rust/crates/cli/src/codex_oauth_flow.rs:174
"<html><body style='background:#131010;color:#f1ecec;display:flex;justify-content:center;align-items:center;height:100vh;font-family:system-ui'>\
<div style='text-align:center'><h1>Authorization Successful</h1><p>You can close this window and return to Claurst.</p></div>\
<script>setTimeout(()=>window.close(),2000)</script></body></html>"
} else {
"<html><body style='background:#131010;color:#f1ecec;display:flex;justify-content:center;align-items:center;height:100vh;font-family:system-ui'>\
<div style='text-align:center'><h1 style='color:#fc533a'>Authorization Failed</h1><p>Check the terminal for details.</p></div></body></html>"
};
let response = format!(
"HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: {}\r\nConnection: close\r\n\r\n{}",
html.len(),
html
);
// Drop the BufReader so we can write back on the socket
drop(reader);
let _ = socket.write_all(response.as_bytes()).await;
let _ = socket.shutdown().await;
if !error.is_empty() {
bail!("OAuth error: {}", error);
}
if code.is_empty() || state.is_empty() {
bail!("Missing code or state in OAuth callback");
}
Ok((code, state))
}
/// Exchange authorization code for access tokens.
async fn exchange_code_for_tokens(code: &str, verifier: &str) -> anyhow::Result<CodexTokens> {
let client = reqwest::Client::new();
let params = [
("client_id", CODEX_CLIENT_ID),
("code", code),
("code_verifier", verifier),
("grant_type", "authorization_code"),
("redirect_uri", CODEX_REDIRECT_URI),
View on GitHub (pinned to b0637c97ec)