[Bug]: MCP SSE transport rejects concurrent requests on connect with "Received request before initialization was complete" (-32602)
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 66/100
- Tipo de issue
- Error
- Claridad
- Bastante claro
- Estado de actividad
- Activo
- Stack tecnológico
- python
- Área
- api, backend-api-design
Línea de trabajo
Start with /app/mcp_bridge.py, comparing the /mcp/ws initialization gate with the SSE /mcp/sse and /mcp/messages flow through SseServerTransport. Reproduce with parallel tools/call requests during the initialize handshake and inspect the resulting session behavior. Done means concurrent SSE requests no longer fail with the pre-initialization -32602 response.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
crawl4ai version
0.9.2 (Docker server, unclecode/crawl4ai:latest)
Expected Behavior
When an MCP client (such as OpenCode, Claude Code, or multi-agent runtimes) connects over SSE (/mcp/sse) and issues tool calls, inbound requests arriving while initialization is completing should either be briefly buffered/queued or await initialization before processing, similar to how /mcp/ws gates incoming traffic.
Current Behavior
When a client establishes an SSE connection and dispatches tool calls concurrently (e.g. parallel fan-out upon connecting), the requests hit /mcp/messages/?session_id=... before the initialize -> notifications/initialized handshake has completed inside mcp.server.session.ServerSession.
This causes mcp/server/session.py to raise:
WARNING - Failed to validate request: Received request before initialization was complete
The client receives:
{"jsonrpc": "2.0", "id": 1, "error": {"code": -32602, "message": "Invalid request parameters"}}
The error code -32602 misleads clients into reporting that tool call parameters are malformed, when in reality the arguments were never validated because the transport rejected the uninitialized session state.
Context & Contrast with WebSocket
In /app/mcp_bridge.py, the WebSocket handler (/mcp/ws) explicitly mitigates this race condition by synchronizing on initialization:
# /app/mcp_bridge.py (WebSocket handler)
first = adapter.validate_python(await ws.receive_json())
await c2s_send.send(first)
await init_done.wait() # <-- explicitly waits for server readiness
while True:
data = await ws.receive_json()
await c2s_send.send(adapter.validate_python(data))
However, the SSE transport (/mcp/sse + /mcp/messages) directly passes through Starlette to SseServerTransport:
sse = SseServerTransport(f"{base}/messages/")
Without any gating on incoming POST requests during the handshake window, any concurrent requests arriving in the first ~100–500ms get rejected.
Upstream References
This is a known race condition in the underlying Python SDK:
- modelcontextprotocol/python-sdk #2583: "Race condition between SSE session init and tools/call rejection (-32602)"
- modelcontextprotocol/python-sdk #423: "MCP SSE Server: Received request before initialization was complete"
Suggested Fix
A minimal fix in mcp_bridge.py for the SSE transport:
- Wrap or intercept incoming POST messages to
/mcp/messagesto await session initialization (with a small timeout, e.g. 2.0s) before feeding them to the read stream writer, OR - Provide an
init_doneevent per SSE session matching the WebSocket pattern.
Steps to Reproduce
- Connect an MCP client over SSE (
/mcp/sse). - Immediately upon receiving the
endpointSSE event, dispatch 3+ paralleltools/callrequests in under 50ms alongsideinitialize. - Observe
Received request before initialization was completein Docker logs and-32602returned to the client.
Environment
- Docker container
unclecode/crawl4ai:latest(0.9.2) - Python 3.12 (inside container)
- Client: OpenCode / Claude Code via SSE transport
- Lenguaje dominante
- Python
- Estrellas
- 84.5k
- Forks
- 8.7k
- Merge medio
- 3 d 9 h
- PR fusionados (30 d)
- 17
Preparar el entorno
- Incluye un Dockerfile o un archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de unclecode/crawl4ai
-
[Bug]: Reusing BFSDeepCrawlStrategy leaks the previous crawl's max_pages budget into a fresh runAbierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
unclecode/crawl4ai#2309 · 2 comentarios ·
Los mantenedores suelen responder en 1 día
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 84/100
unclecode/crawl4ai#2147 · 3 comentarios ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
unclecode/crawl4ai#2123 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
🐞 Bug 🩺 Needs Triage
Dificultad 4/5 3-5 días Aptitud para principiantes 55/100
Los mantenedores suelen responder en 1 día
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 35/100
Los mantenedores suelen responder en 1 día
Todos los issues de unclecode/crawl4ai
Issues similares
-
customer-reported
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
Azure/azure-cli#34150 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
community-request
Dificultad 1/5 Menos de una hora Aptitud para principiantes 95/100
NVIDIA-NeMo/Curator#2464 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
weblate-discover crashes with an unhandled FileNotFoundError when the directory does not existAbierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
WeblateOrg/translation-finder#1099 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
trezor/trezor-firmware#7997 ·
Los mantenedores suelen responder en 2 días
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
Los mantenedores suelen responder en 1 día