Skip to content

fix(session): return INVALID_REQUEST error instead of crashing on pre-init requests#2411

Open
Smeet23 wants to merge 1 commit into
modelcontextprotocol:mainfrom
Smeet23:fix/sse-uninit-request-error
Open

fix(session): return INVALID_REQUEST error instead of crashing on pre-init requests#2411
Smeet23 wants to merge 1 commit into
modelcontextprotocol:mainfrom
Smeet23:fix/sse-uninit-request-error

Conversation

@Smeet23
Copy link
Copy Markdown

@Smeet23 Smeet23 commented Apr 9, 2026

Problem

When an MCP client sends a request (e.g. tools/list) before completing the initialize handshake, the server raises a RuntimeError that propagates through the anyio task group and crashes the entire ASGI application:

RuntimeError: Received request before initialization was complete
ExceptionGroup: unhandled errors in a TaskGroup
ERROR: Exception in ASGI application

This affects real-world clients such as Cursor, MCP Inspector, and anything-llm that skip re-initialization after a server restart or dropped SSE connection. The server dies instead of returning a useful error.

Fixes #423.

Solution

Replace the raise RuntimeError(...) in ServerSession._received_request with a proper JSON-RPC INVALID_REQUEST (-32600) error response sent via the responder. The server stays alive and the client receives a meaningful error it can act on.

# Before
case _:
    if self._initialization_state != InitializationState.Initialized:
        raise RuntimeError("Received request before initialization was complete")

# After
case _:
    if self._initialization_state != InitializationState.Initialized:
        with responder:
            await responder.respond(
                ErrorData(
                    code=INVALID_REQUEST,
                    message="Received request before initialization was complete",
                )
            )
        return

Test

Added test_request_before_initialization_returns_error to tests/server/test_session.py that sends a tools/list request without any prior initialize handshake and asserts that:

  • The server returns a JSONRPCError with code INVALID_REQUEST
  • The server does not crash (no ExceptionGroup)

…-init requests

When an MCP client sends a request (e.g. tools/list) before completing
the initialize handshake, the server now responds with a proper
INVALID_REQUEST JSON-RPC error instead of raising a RuntimeError that
propagates through the anyio task group and crashes the ASGI application.

This affects real-world clients such as Cursor, MCP Inspector, and
anything-llm that skip re-initialization after a server restart or
dropped SSE connection.

Github-Issue: modelcontextprotocol#423
@Smeet23
Copy link
Copy Markdown
Author

Smeet23 commented Apr 17, 2026

Hi team — just a gentle ping on this PR. All checks are passing. Would appreciate a review when you get a chance. Happy to address any feedback. Thanks!

@Luxian
Copy link
Copy Markdown

Luxian commented May 23, 2026

Thanks @Smeet23 for putting this patch together.

We build an MCP server using this library and bundle it in Docker. Whenever we rebuild the image, connected clients have to reconnect to the new container. If we forget to reconnect the client, its next tool call hits this pre-init path and the user (or the AI agent driving the client) sees -32602 "Invalid request parameters" with no further detail. From the client's POV that looks indistinguishable from a real param-validation failure, so debugging starts at the wrong layer.

We worked around it with a monkey-patch on ServerSession._received_request that returns -32002 with a descriptive data field naming the cause and the fix. With the patch in place, the agent now reports something like "looks like the server restarted, run /mcp reconnect" on its own. Real diagnostic time saved.

This PR would make our workaround obsolete: it solves the same problem at the source, in a cleaner way (uses the spec-aligned INVALID_REQUEST code and routes through responder.respond instead of writing to the stream directly). We hope this gets merged soon. Happy to test against our setup if it helps unblock review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MCP SSE Server: Received request before initialization was complete

3 participants