{"record":{"id":"021e8aa9c8087270","repo":"aaif-goose/goose","slug":"oauth-authentication-failed-for","errorCode":null,"errorMessage":"OAuth authentication failed for {}: {}","messagePattern":"OAuth authentication failed for (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/goose-cli/src/commands/configure.rs","lineNumber":459,"sourceCode":"}\n\n/// Helper function to handle OAuth configuration for a provider\nasync fn handle_oauth_configuration(provider_name: &str, key_name: &str) -> anyhow::Result<()> {\n    let _ = cliclack::log::info(format!(\n        \"Configuring {} using OAuth device code flow...\",\n        key_name\n    ));\n\n    // Create a temporary provider instance to handle OAuth\n    match create(provider_name, Vec::new()).await {\n        Ok(provider) => match provider.configure_oauth().await {\n            Ok(_) => {\n                let _ = cliclack::log::success(\"OAuth authentication completed successfully!\");\n                Ok(())\n            }\n            Err(e) => {\n                let _ = cliclack::log::error(format!(\"Failed to authenticate: {}\", e));\n                Err(anyhow::anyhow!(\n                    \"OAuth authentication failed for {}: {}\",\n                    key_name,\n                    e\n                ))\n            }\n        },\n        Err(e) => {\n            let _ = cliclack::log::error(format!(\"Failed to create provider for OAuth: {}\", e));\n            Err(anyhow::anyhow!(\n                \"Failed to create provider for OAuth: {}\",\n                e\n            ))\n        }\n    }\n}\n\nconst UNLISTED_MODEL_KEY: &str = \"__unlisted__\";\n","sourceCodeStart":441,"sourceCodeEnd":477,"githubUrl":"https://github.com/aaif-goose/goose/blob/3810898a7447ec3299be72e223d3570a7aabf0ab/crates/goose-cli/src/commands/configure.rs#L441-L477","documentation":"During `goose configure`, provider OAuth is exercised by creating the provider and calling `configure_oauth()`. When the OAuth flow itself fails, the error is wrapped with this message; the placeholders carry the secret key name and the underlying provider error, and cliclack has already printed 'Failed to authenticate: ...' with the same cause.","triggerScenarios":"Selecting OAuth sign-in for a provider in `goose configure` when the browser-based flow fails: the localhost callback is unreachable, the provider rejects the client request, the user cancels, or the token exchange errors.","commonSituations":"SSH/headless machines where no browser can open the callback; corporate proxies blocking localhost callbacks; expired or misconfigured OAuth client registration; provider outages.","solutions":["Read the appended underlying error text — it states the actual failure (callback, exchange, cancellation)","Ensure a browser can open and reach the localhost redirect","Retry the flow once; transient callback races do occur","Fall back to manual API-key authentication for that provider if it supports one"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Rust: retry transient OAuth failures, keep the provider error chain\nfor attempt in 0..2 {\n    match provider.configure_oauth().await {\n        Ok(_) => break,\n        Err(e) if attempt == 1 => return Err(anyhow::anyhow!(\"OAuth authentication failed: {e}\")),\n        Err(_) => tokio::time::sleep(std::time::Duration::from_secs(2)).await,\n    }\n}","preventionTips":["Run OAuth flows on machines with a working browser","Keep an API-key fallback documented for headless setups","Read the underlying error string: it distinguishes user cancel from outage"],"tags":["oauth","authentication","provider","network","cli"],"backgroundTag":null,"analyzedSha":"3810898a7447ec3299be72e223d3570a7aabf0ab","analyzedAt":"2026-08-16T10:14:26.282Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}