Hmbown/CodeWhale · error · anyhow::Error
MCP operation on plugin server '{}' was cancelled after auth
Error message
MCP operation on plugin server '{}' was cancelled after authority changed: {reason} What it means
finish_guarded_error wraps every error coming out of a connection operation and checks the shared authority_revocation_reason lock. If a reviewed plugin bundle's authority (catalog hash/source) was revoked or changed while an operation was in flight, the transport is shut down, the state set to Disconnected, and this error replaces the original one. It is a security guard: stale plugin connections must not keep operating under an authority that no longer approves them.
Source
Thrown at crates/tui/src/mcp.rs:2265
}
fn catalog_authorized(&self) -> bool {
self.config
.reviewed_plugin
.as_ref()
.is_none_or(ReviewedPluginMcpSource::catalog_is_current)
}
async fn finish_guarded_error<T>(&mut self, error: anyhow::Error) -> Result<T> {
let reason = self
.authority_revocation_reason
.lock()
.ok()
.and_then(|reason| reason.clone());
if let Some(reason) = reason {
self.transport.shutdown().await;
self.state = ConnectionState::Disconnected;
anyhow::bail!(
"MCP operation on plugin server '{}' was cancelled after authority changed: {reason}",
self.name
);
}
Err(error)
}
}
/// Apply the ambient proxy policy for MCP HTTP transports.
///
/// User-authored MCP configuration keeps the long-standing corporate-proxy
/// behavior. Reviewed plugin bundles deliberately do not: proxy URLs can carry
/// credentials and proxy processes can observe request metadata, neither of
/// which is part of the v1 reviewed remote authority. Return before consulting
/// the environment so even reading ambient proxy credentials is impossible on
/// that path, and call `no_proxy` explicitly to keep this invariant stable if
/// reqwest's defaults change.
fn configure_mcp_proxy<F>(View on GitHub (pinned to 8880682c63)
Solutions
- Update or re-approve the reviewed plugin bundle so its catalog is current, then reconnect — get_or_connect revalidates via validate_before_use.
- Do not retry blindly: the error means the running code is no longer authorized; surface it to the user or operator.
- If the revocation was accidental, restore the exact reviewed plugin files/catalog so the hash matches again.
- Check for concurrent processes mutating the plugin registry workspace.
Example fix
// before
match conn.call_tool(name, args, t).await { Err(e) => retry(e) } // loops forever on authority revocation
// after
match conn.call_tool(name, args, t).await {
Err(e) if e.to_string().contains("authority changed") => {
return Err(e); // terminal: surface to user, re-approve plugin first
}
other => other,
} Defensive patterns
Strategy: try-catch
Try / catch
// Rust: terminal security error — never auto-retry
match result {
Err(e) if e.to_string().contains("authority changed") => {
tracing::error!("plugin authority revoked mid-operation: {e:#}");
return Err(e); // user must re-approve the plugin bundle
}
other => other,
} Prevention
- Never write retry loops that swallow authority-revocation errors.
- Re-approve or update the reviewed plugin bundle before reconnecting.
- Expect get_or_connect to refuse the server afterwards via validate_before_use — that is the same guard, do not bypass it.
When it happens
Trigger: A tool call is in flight on a reviewed-plugin MCP server when the plugin catalog is updated or the plugin's review state is revoked — validate_before_use in get_or_connect will then refuse future use, and finish_guarded_error converts already-started operations into this cancellation error.
Common situations: Plugin bundle upgraded while the session held open connections; a security review revoked the plugin between turns; CI environments that mutate the plugin registry concurrently with tool execution.
Related errors
- Refusing to {operation} MCP server '{server_name}' from plug
- reviewed plugin stage could not be opened for launch
- reviewed plugin stdio cwd escaped its staged root
- Refusing MCP server '{server_name}': its remote endpoint no
- reviewed plugin executable bytes changed before spawn
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/5aed354c530425e8.
Report an issue: GitHub.