Kuberwastaken/claurst · error · anyhow::Error
Failed to open browser for OAuth
Error message
Failed to open browser for OAuth: {} What it means
The `open` crate failed to launch the system browser (or URL handler) for the MCP OAuth authorization URL. The auth session had already bound its callback listener; the failure is environment-level — no default browser configured, headless/session environment without a URL opener, or the OS handler returned an error.
Solutions
- Set BROWSER / default browser environment variables and retry
- Copy the authorization URL from logs and open it manually in a browser within the 180s callback timeout
- On headless systems, run the auth flow from a machine with a desktop session
Defensive patterns
Strategy: fallback
When it happens
Trigger: Thrown at src-rust/crates/mcp/src/oauth.rs:305 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/70cca9aadc1309ca.
Report an issue: GitHub.
Appendix: source
Thrown at src-rust/crates/mcp/src/oauth.rs:305
.query_pairs()
.find(|(key, _)| key == "state")
.map(|(_, value)| value.to_string());
if received_state.as_deref() != Some(expected_state) {
anyhow::bail!("OAuth state mismatch — possible CSRF attack");
}
}
parsed_url
.query_pairs()
.find(|(key, _)| key == "code")
.map(|(_, value)| value.to_string())
.ok_or_else(|| anyhow::anyhow!("OAuth callback did not contain an authorization code"))
}
pub async fn run_mcp_auth_session(session: McpAuthSession) -> anyhow::Result<McpAuthResult> {
let (listener, host, callback_path) = bind_callback_listener(&session.redirect_uri).await?;
open::that(&session.auth_url)
.map_err(|e| anyhow::anyhow!("Failed to open browser for OAuth: {}", e))?;
let code = wait_for_authorization_code(listener, &host, &callback_path, None).await?;
let mut token = exchange_code(
&session.metadata.token_endpoint,
&code,
&session.verifier,
&session.redirect_uri,
)
.await?;
token.server_name = session.server_name.clone();
store_mcp_token(&token).map_err(|e| {
anyhow::anyhow!(
"Failed to store MCP token for '{}': {}",
session.server_name,
e
)
})?;
View on GitHub (pinned to b0637c97ec)