{"record":{"id":"1977cee6c77cdd5a","repo":"Kuberwastaken/claurst","slug":"timeout-waiting-for-oauth-callback","errorCode":null,"errorMessage":"Timeout waiting for OAuth callback","messagePattern":"Timeout waiting for OAuth callback","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src-rust/crates/mcp/src/oauth.rs","lineNumber":246,"sourceCode":"    } else {\n        redirect_url.path().to_string()\n    };\n    let listener = TcpListener::bind((host.as_str(), port))\n        .await\n        .map_err(|e| anyhow::anyhow!(\"Failed to bind OAuth callback listener on {}:{}: {}\", host, port, e))?;\n\n    Ok((listener, host, callback_path))\n}\n\nasync fn wait_for_authorization_code(\n    listener: TcpListener,\n    host: &str,\n    callback_path: &str,\n    expected_state: Option<&str>,\n) -> anyhow::Result<String> {\n    let (mut socket, _) = tokio::time::timeout(Duration::from_secs(180), listener.accept())\n        .await\n        .map_err(|_| anyhow::anyhow!(\"Timeout waiting for OAuth callback\"))?\n        .map_err(|e| anyhow::anyhow!(\"Failed to accept OAuth callback connection: {}\", e))?;\n\n    let (reader, mut writer) = socket.split();\n    let mut reader = BufReader::new(reader);\n    let mut request_line = String::new();\n    reader\n        .read_line(&mut request_line)\n        .await\n        .map_err(|e| anyhow::anyhow!(\"Failed to read OAuth callback request: {}\", e))?;\n    loop {\n        let mut header = String::new();\n        reader\n            .read_line(&mut header)\n            .await\n            .map_err(|e| anyhow::anyhow!(\"Failed to read OAuth callback headers: {}\", e))?;\n        if header.trim().is_empty() {\n            break;\n        }","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/Kuberwastaken/claurst/blob/b0637c97ec34144387cbf2f74f65df6d16a6cef1/src-rust/crates/mcp/src/oauth.rs#L228-L264","documentation":"wait_for_authorization_code wraps listener.accept() in a 180-second tokio timeout; if no browser connects to the callback within that window the timeout fires and this error is raised. The library gives up rather than blocking forever on a user who never completes the browser authorization.","triggerScenarios":"run_mcp_auth_session opened the auth URL but no HTTP request hits the local callback listener within 3 minutes — browser never opened, user closed the tab, or the redirect points at the wrong port/path.","commonSituations":"User ignores or misses the browser tab; headless/SSH environment with no browser; redirect URI port in config differs from the bound listener so the provider redirects elsewhere; slow 2FA/login flow exceeding 180s.","solutions":["Re-run the auth flow and complete the browser authorization promptly (within 3 minutes)","Open the printed authorization URL manually if no browser launched","Verify the configured redirect URI matches the listener port so the provider redirects to the local server","In headless environments, forward the callback port (ssh -L) or use a device-code flow instead"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"loop {\n    match run_mcp_auth_flow(url).await {\n        Ok(s) => break s,\n        Err(e) if e.to_string().contains(\"Timeout waiting\") => {\n            eprintln!(\"No callback within 180s; reopening browser...\");\n            open_browser(url);\n        }\n        Err(e) => return Err(e),\n    }\n}","preventionTips":["Complete the browser authorization promptly after starting the flow","Run in an environment where the auth URL can be opened (or forward the port)","Ensure the redirect URI port matches the listener so the browser reaches the callback"],"tags":["oauth","timeout","browser"],"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"}