zed-industries/zed · warning · anyhow::Error

MCP tool cancelled by user

Error message

MCP tool cancelled by user

What it means

The user cancelled the agent run while an MCP tool was executing: in the `futures::select!`, `event_stream.cancelled_by_user()` won the race against the in-flight JSON-RPC `CallTool` request. The call is deliberately aborted with this message; the underlying request future is dropped without a response.

Source

Thrown at crates/agent/src/tools/context_server_registry.rs:391

            log::trace!(
                "Running tool: {} with arguments: {:?}",
                tool_name,
                arguments
            );

            let request = protocol.request::<context_server::types::requests::CallTool>(
                context_server::types::CallToolParams {
                    name: tool_name,
                    arguments,
                    meta: None,
                },
            );

            let response = futures::select! {
                response = request.fuse() => response?,
                _ = event_stream.cancelled_by_user().fuse() => {
                    return Err(anyhow::anyhow!("MCP tool cancelled by user").into());
                }
            };

            if response.is_error == Some(true) {
                let error_message: String =
                    response.content.iter().filter_map(|c| c.text()).collect();
                return Err(anyhow::anyhow!(error_message).into());
            }

            let mut llm_output = Vec::new();
            let mut tool_call_content = Vec::new();
            let mut concatenated_text = String::new();
            for content in response.content {
                match content {
                    context_server::types::ToolResponseContent::Text { text } => {
                        concatenated_text.push_str(&text);
                        tool_call_content.push(acp::ToolCallContent::Content(acp::Content::new(
                            acp::ContentBlock::Text(acp::TextContent::new(text.clone())),

View on GitHub (pinned to bc538def45)

Solutions

  1. Treat it as a normal cancellation: stop the run cleanly and do not retry automatically.
  2. Make long-running MCP tools report progress so users wait instead of cancelling.
  3. Design server-side tools idempotent so an aborted call can be safely re-run later.
Defensive patterns

Strategy: try-catch

Try / catch

let response = futures::select! {
    response = request.fuse() => response?,
    _ = event_stream.cancelled_by_user().fuse() => {
        // User pressed stop: end as a cancellation, not a tool failure.
        return Err(anyhow::anyhow!("tool run cancelled").into());
    }
};

Prevention

When it happens

Trigger: Pressing stop/cancel during a long-running MCP tool (builds, test suites, web fetches served by MCP) or closing the agent panel while the request is in flight.

Common situations: Slow MCP servers whose tools run for minutes; accidental stops; tools invoked twice where the user cancels one.

Related errors


AI-assisted analysis of zed-industries/zed@bc538def45 (2026-08-16). Data as JSON: /api/errors/134b1c7e115646fa. Report an issue: GitHub.