Skip to content

Server rejects requests after SSE reconnect because client skips initialize handshake #2214

@chriscoey

Description

@chriscoey

Problem

When an SSE client reconnects after a server restart, it may send requests (e.g. tools/list) without first re-sending InitializeRequest. The server session is in NotInitialized state and rejects every request with -32602.

The session is permanently stuck — there's no recovery path. The client would need to disconnect and reconnect with a fresh initialize to fix it.

Where it happens

In src/mcp/server/session.py, _received_request():

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

This exception is caught in shared/session.py and returned as JSON-RPC error -32602 (INVALID_PARAMS), which gives no indication that the real problem is a missing initialize handshake.

Suggestion

The server could be more resilient here. Two ideas:

  1. Return a specific error code (e.g. -32002 or a custom code) with a message like "Session not initialized — send InitializeRequest first" instead of the generic -32602. This would let clients detect and recover from the situation.

  2. Queue or defer pre-init requests briefly instead of rejecting them immediately. This would handle the race where the client sends a request before the server's session handler is fully ready, which can happen even when the client does send initialize (the SSE transport sends the endpoint URL before the session loop is running).

Context

This interacts with the SSE reconnect behavior described in anthropics/claude-code#30224. The client side should re-send initialize on reconnect, but a more informative error from the server would make the failure mode obvious and recoverable rather than a silent permanent breakage.

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