{"record":{"id":"58fb4bfda4283873","repo":"aaif-goose/goose","slug":"failed-to-receive-authorization-code","errorCode":null,"errorMessage":"Failed to receive authorization code","messagePattern":"Failed to receive authorization code","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/goose/src/config/signup_openrouter/mod.rs","lineNumber":91,"sourceCode":"    /// Start local server and wait for callback\n    pub async fn start_server(&mut self) -> Result<String> {\n        let (code_tx, code_rx) = oneshot::channel::<String>();\n        let (shutdown_tx, shutdown_rx) = oneshot::channel::<()>();\n\n        // Store shutdown sender so we can stop the server later\n        self.server_shutdown_tx = Some(shutdown_tx);\n\n        // Start the server in a background task\n        tokio::spawn(async move {\n            if let Err(e) = server::run_callback_server(code_tx, shutdown_rx).await {\n                eprintln!(\"Server error: {}\", e);\n            }\n        });\n\n        // Wait for the authorization code with timeout\n        match timeout(AUTH_TIMEOUT, code_rx).await {\n            Ok(Ok(code)) => Ok(code),\n            Ok(Err(_)) => Err(anyhow!(\"Failed to receive authorization code\")),\n            Err(_) => Err(anyhow!(\"Authentication timeout - please try again\")),\n        }\n    }\n\n    pub async fn exchange_code(&self, code: String) -> Result<String> {\n        let client = Client::new();\n\n        let request_body = TokenRequest {\n            code: code.clone(),\n            code_verifier: self.code_verifier.clone(),\n            code_challenge_method: \"S256\".to_string(),\n        };\n\n        eprintln!(\"Exchanging code for API key...\");\n        eprintln!(\"Code: {}\", code);\n        eprintln!(\"Code verifier length: {}\", self.code_verifier.len());\n        eprintln!(\"Code challenge: {}\", self.code_challenge);\n","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/aaif-goose/goose/blob/3810898a7447ec3299be72e223d3570a7aabf0ab/crates/goose/src/config/signup_openrouter/mod.rs#L73-L109","documentation":"During OpenRouter signup, a localhost callback server (run_callback_server) forwards the OAuth authorization code over a tokio channel. The receiver gets Ok(Err(_)) — this error — when the channel's sender is dropped without delivering a code, i.e. the server task exited before receiving the callback. It is distinct from the sibling timeout error (AUTH_TIMEOUT elapsed).","triggerScenarios":"The spawned server task fails to bind the callback port (already in use) or panics, dropping code_tx; the browser never reaches the callback because the server is gone. The real cause is printed to stderr as `Server error: ...`.","commonSituations":"A previous signup attempt left a process holding the callback port; running multiple `goose signup` flows concurrently; sandboxed environments where the local listener fails to start.","solutions":["Check stderr for the `Server error: ...` line — for a bind failure, free the callback port (stop the other flow / kill the stale process) and retry","Do not run two signup flows at once on the same machine","If the server error persists, retry after a moment — a fresh flow re-binds the listener"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Before starting the flow, confirm the callback port is free:\nlet listener = std::net::TcpListener::bind((\"127.0.0.1\", port));\nif listener.is_err() {\n    // another signup flow owns the port: abort with a clear message instead of a channel drop\n}\ndrop(listener);","typeGuard":null,"tryCatchPattern":"match signup.wait_for_code().await {\n    Err(e) if e.to_string() == \"Failed to receive authorization code\" => {\n        // server task died (see stderr 'Server error'); free the port and restart the whole flow\n    }\n    Err(e) if e.to_string().starts_with(\"Authentication timeout\") => {\n        // user never completed the browser step; restart flow and remind them to finish it\n    }\n    other => other?,\n}","preventionTips":["Run one signup flow at a time per machine","Check stderr for the 'Server error:' line whenever this fires — it holds the bind/panic cause","Ensure local loopback listeners are permitted in sandboxed environments"],"tags":["auth","oauth","openrouter","network"],"backgroundTag":null,"analyzedSha":"3810898a7447ec3299be72e223d3570a7aabf0ab","analyzedAt":"2026-08-16T10:14:26.282Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}