Hmbown/CodeWhale · warning

MCP OAuth setup cancelled after plugin authority changed

Error message

MCP OAuth setup cancelled after plugin authority changed

What it means

During MCP server setup that involves OAuth, the runtime is built inside tokio::select! with the session cancel token racing the OAuth client construction. If cancellation wins (because the plugin authority — the reviewed-plugin generation governing the server's permissions — changed), the setup is aborted with this bail. The operation was made stale by a concurrent policy/authority change, so it must not proceed.

Solutions

  1. Retry the MCP server connection after the plugin authority change settles
  2. Re-review/re-approve the plugin so its generation is current, then reconnect
  3. Avoid changing plugin permissions while an MCP OAuth handshake is in flight
  4. Restart the session if the cancel token remains latched
Defensive patterns

Strategy: retry

Try / catch

match connect(name).await {
    Err(e) if e.to_string().contains("plugin authority changed") => {
        // wait for the authority to settle, then retry once
        tokio::time::sleep(Duration::from_secs(1)).await;
        connect(name).await
    }
    other => other,
}

Prevention

When it happens

Trigger: An MCP OAuth setup flow is in flight when the reviewed plugin authority changes (plugin re-review, revocation, or generation bump), firing cancel_token.cancelled() before the OAuth runtime finishes constructing.

Common situations: A plugin's permissions are revoked or re-approved by a concurrent process while the user is mid-OAuth; editing/reviewing plugin settings during a connecting MCP server's OAuth handshake.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/c880d5361ecc49d1. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/mcp.rs:1722

            }
            let client = http_client::McpHttpClient::new(
                url,
                config.runtime_added,
                config.reviewed_plugin.is_some(),
                config.allow_private_network,
                network_policy,
                Duration::from_secs(connect_timeout_secs),
                Duration::from_secs(read_timeout_secs),
            )?;
            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_with_client(
                                &name,
                                &config,
                                default_headers,
                                client.clone(),
                            ) => 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 73e0f67d83)