Hmbown/CodeWhale · warning · anyhow::Error
MCP OAuth setup cancelled after plugin authority changed
Error message
MCP OAuth setup cancelled after plugin authority changed
What it means
While preparing OAuth for an HTTP MCP server, connect_with_policy races McpOAuthRuntime::from_server_config against the connection's CancellationToken in a biased select (crates/tui/src/mcp.rs:1551-1563). If the token fires first - the cross-process authority watcher revoked a plugin receipt, or the setup was torn down - OAuth preparation aborts with this message instead of continuing half-configured. It is a transient cancellation, not a permanent failure.
Source
Thrown at crates/tui/src/mcp.rs:1554
} else {
attempt.stop()
}
}));
}
client_builder =
configure_mcp_proxy(client_builder, config.reviewed_plugin.is_some(), |name| {
std::env::var(name)
});
let client = client_builder.build()?;
let oauth_runtime = if config.reviewed_plugin.is_some() {
None
} else {
match oauth::build_default_headers(&config.headers, &config.env_headers) {
Ok(default_headers) => {
let prepared = tokio::select! {
biased;
_ = cancel_token.cancelled() => {
anyhow::bail!(
"MCP OAuth setup cancelled after plugin authority changed"
)
}
prepared = oauth::McpOAuthRuntime::from_server_config(
&name,
&config,
default_headers,
) => prepared,
};
match prepared {
Ok(runtime) => runtime,
Err(err) => {
if config.reviewed_plugin.is_some() {
tracing::warn!(
target: "mcp",
server = %name,
"failed to prepare reviewed plugin MCP OAuth runtime; provider details suppressed; continuing without stored OAuth token"
);View on GitHub (pinned to 8880682c63)
Solutions
- Retry the connect once plugin/config churn has settled - the race is transient by construction.
- Avoid running /plugin trust, /plugin revoke or /plugin reload concurrently with live MCP connections.
- If it recurs, fix reachability/latency of the authorization server's metadata endpoint so OAuth preparation completes quickly.
Example fix
// before
let conn = McpConnection::connect_with_policy(name, cfg, &timeouts, policy).await?;
// after: retry once on this transient cancellation
let conn = match McpConnection::connect_with_policy(name, cfg.clone(), &timeouts, policy).await {
Ok(conn) => conn,
Err(err) if err.to_string().contains("OAuth setup cancelled") => {
McpConnection::connect_with_policy(name, cfg, &timeouts, policy).await?
}
Err(err) => return Err(err),
}; Defensive patterns
Strategy: retry
Try / catch
let conn = match McpConnection::connect_with_policy(name, cfg.clone(), &timeouts, policy).await {
Ok(conn) => conn,
Err(err) if err.to_string().contains("OAuth setup cancelled") => {
// Transient cancellation race; safe to retry after churn settles.
McpConnection::connect_with_policy(name, cfg, &timeouts, policy).await?
}
Err(err) => return Err(err),
}; Prevention
- Do not run /plugin trust / revoke / reload while MCP connections are being established.
- Avoid two instances sharing a plugin directory while one reconnects.
- Keep authorization-server metadata endpoints fast and reachable.
When it happens
Trigger: A plugin trust/revoke/reload in another process lands exactly while OAuth token storage or dynamic client registration is being read; connection teardown races a slow authorization-server metadata fetch.
Common situations: Two TUI instances sharing a plugin directory; /plugin reload executed during startup; slow or flaky OAuth metadata endpoints widening the race window.
Related errors
- MCP connection '{}' was cancelled
- MCP session preflight cancelled after plugin authority chang
- xAI OAuth lifecycle lock was poisoned
- MCP catalog changed after tool resolution; retry the call
- Reviewed plugin MCP authentication failed (provider details
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/c880d5361ecc49d1.
Report an issue: GitHub.