Skip to content

CancelledError causes duplicate response and server crash #1152

@lukacf

Description

@lukacf

Initial Checks

Description

When a client cancels a long-running tool call (e.g., user hits Escape in Claude Code), the MCP server crashes with an assertion error and becomes unresponsive.

What I'm seeing:

  • Server crashes with "AssertionError: Request already responded to"
  • All subsequent requests fail
  • Server must be restarted

What I expect:

  • Server should handle cancellation gracefully
  • Server should remain responsive for subsequent requests

Root cause:
In Server._handle_request, when a CancelledError occurs:

  1. RequestResponder.cancel() has already sent an error response
  2. The CancelledError propagates to _handle_request
  3. It tries to send another error response
  4. This triggers "already responded to" assertion

Example Code

from mcp.server import Server
import asyncio

server = Server("test-server")

@server.call_tool()
async def slow_tool(name: str, arguments: dict):
    # Any long-running operation
    await asyncio.sleep(30)
    return [{"type": "text", "text": "Done"}]

# When client calls slow_tool and cancels (e.g., hits Escape in Claude Code)
# Server crashes with: AssertionError: Request already responded to

Python & MCP Python SDK

Python 3.8+ (tested on 3.11)
MCP Python SDK: Latest version from main branch

Related issues: jlowin/fastmcp#508, jlowin/fastmcp#823

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions