{"record":{"id":"697fe7ea73e358cf","repo":"Kuberwastaken/claurst","slug":"oauth-callback-timeout-5-minutes","errorCode":null,"errorMessage":"OAuth callback timeout (5 minutes)","messagePattern":"OAuth callback timeout \\(5 minutes\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src-rust/crates/cli/src/codex_oauth_flow.rs","lineNumber":120,"sourceCode":"    let tokens = exchange_code_for_tokens(&code, &verifier).await?;\r\n\r\n    // Persist tokens and register an account profile in the registry.\r\n    claurst_core::oauth_config::save_codex_tokens_and_register(&tokens, label)?;\r\n\r\n    eprintln!(\"Codex login successful!\");\r\n    Ok(tokens)\r\n}\r\n\r\n/// Wait for OAuth callback on local server, extract code and state.\r\nasync fn wait_for_callback(listener: TcpListener) -> anyhow::Result<(String, String)> {\r\n    use tokio::io::AsyncWriteExt;\r\n\r\n    let (mut socket, _) = tokio::time::timeout(\r\n        std::time::Duration::from_secs(300), // 5 minute timeout\r\n        listener.accept(),\r\n    )\r\n    .await\r\n    .map_err(|_| anyhow!(\"OAuth callback timeout (5 minutes)\"))?\r\n    .map_err(|e| anyhow!(\"Failed to accept connection: {}\", e))?;\r\n\r\n    let mut reader = BufReader::new(&mut socket);\r\n    let mut request_line = String::new();\r\n    reader.read_line(&mut request_line).await?;\r\n\r\n    // Parse \"GET /auth/callback?code=...&state=... HTTP/1.1\"\r\n    let parts: Vec<&str> = request_line.split_whitespace().collect();\r\n    if parts.len() < 2 {\r\n        bail!(\"Invalid HTTP request\");\r\n    }\r\n\r\n    let path = parts[1];\r\n    let query_start = path.find('?').ok_or_else(|| anyhow!(\"No query string in callback\"))?;\r\n    let query = &path[query_start + 1..];\r\n\r\n    let mut code = String::new();\r\n    let mut state = String::new();\r","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/Kuberwastaken/claurst/blob/b0637c97ec34144387cbf2f74f65df6d16a6cef1/src-rust/crates/cli/src/codex_oauth_flow.rs#L102-L138","documentation":"After binding the callback server, the OAuth flow waits up to 5 minutes (300s) for the browser to complete authorization and hit the local callback URL. `tokio::time::timeout` cancels the accept when the deadline passes and the flow converts that into this error. It means the user never completed the browser authorization in time.","triggerScenarios":"`listener.accept()` wrapped in a 300-second `tokio::time::timeout` elapses inside `wait_for_callback` — no callback connection was received before the deadline.","commonSituations":"User switched away and never finished browser login; browser failed to open or the auth URL wasn't visited; the authorization page hung on a captive portal/VPN; user took longer than 5 minutes to enter credentials/2FA.","solutions":["Retry the login and complete the browser authorization promptly (within 5 minutes).","Open the printed auth URL manually if the browser did not launch automatically.","Check network/VPN/proxy issues that might block the redirect back to 127.0.0.1.","If you consistently need longer, the flow must be re-run — the challenge/verifier pair is single-use."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if let Err(e) = run_oauth_flow(&mut app).await {\n    if e.to_string().contains(\"OAuth callback timeout\") {\n        // single-use verifier: restart the whole flow rather than waiting longer\n        prompt_user(\"Login timed out; press Enter to retry\");\n        run_oauth_flow(&mut app).await?;\n    }\n}","preventionTips":["Complete the browser login promptly after the URL opens.","Open the auth URL manually if auto-launch fails.","Avoid VPN/captive-portal networks that stall the redirect during login."],"tags":["oauth","timeout","browser","cli"],"backgroundTag":"request-timeout","analyzedSha":"b0637c97ec34144387cbf2f74f65df6d16a6cef1","analyzedAt":"2026-09-10T00:24:58.650Z","contentChangedAt":"2026-09-10T00:24:58.650Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}