fix(client): contain streamable HTTP POST transport errors - #3584
RaulMermans wants to merge 1 commit into
Conversation
An httpx2.TransportError raised while sending a POST or reading its JSON body escaped _handle_post_request. For a request it crashed the transport task group and tore down the whole session; for a notification it ended post_writer, so every later call failed with CONNECTION_CLOSED. Contain it to the message that caused it: a request is resolved with CONNECTION_CLOSED via _resolve_abandoned_request (the message names the original exception), a notification is dropped, and the exception is logged and forwarded on the read stream so message_handler sees it. Connect-time initialize and server/discover still re-raise the raw error: Client(mode="auto") relies on it to tell an outage from a legacy server (lifecycle:discover:network-error-raises). Refs modelcontextprotocol#1401 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MZ7D3Be8YGBE4jLDo4PFXJ
|
This PR has been closed automatically. This repo only keeps pull requests open when they come from a maintainer, or from a contributor a maintainer has assigned to the linked issue, and you aren't currently assigned to #1401. If a maintainer assigns you to #1401, this PR reopens on its own and there's nothing more you need to do here. Assignment is a maintainer call based on capacity; comments that only ask to be assigned don't factor in. What does help is engaging on the issue itself by confirming the repro, explaining why it matters for your use case, or describing the approach you'd take. You're welcome to keep pushing commits here (just avoid force-pushing, since GitHub can't reopen a rewritten branch), but that on its own won't get the PR reviewed or the issue assigned, and realistically most auto-closed PRs stay closed. There's no need to open a new PR either way. CONTRIBUTING.md has the full reasoning, but in short:
Maintainers: reopen, remove |
|
I reproduced this against current The original SSE hang appears to be fixed by changes including #2005 and #3047, but a related POST-level transport failure remains:
Proposed fix, tested in #3584 (auto-closed pending assignment):
Does this match the intended v2 behavior, in particular keeping the session alive after a per-POST failure and forwarding the original exception to Disclosure: I used AI assistance during the investigation and implementation. I reviewed the behavior, tests, and design decisions and can explain and own the change. |
Fixes #1401
After connection, an
httpx2.TransportErroron one POST now fails only that message: a request getsMCPError(CONNECTION_CLOSED), a notification is dropped, and the session keeps working. Connect-timeinitialize/server/discoverstill raise the raw error.Motivation and Context
The SSE-response hang from #1401 is already fixed on
main(#2005, #3047). A related failure remained inStreamableHTTPTransport._handle_post_request:mainReadTimeouton the POST itself, or while reading a JSON response bodyhttpx2.TransportErrorcrashes the transport task group; the whole session and every in-flight call is torn downpost_writerlogs and exits; every later call fails withCONNECTION_CLOSED_handle_post_requestnow catches onlyhttpx2.TransportError:CONNECTION_CLOSEDvia_resolve_abandoned_request, naming the original exception.post_writerkeeps running.message_handlerreceives it.initialize/server/discover: re-raised unchanged, solifecycle:discover:network-error-raisesholds.No dispatcher, public API or error-type changes.
How Has This Been Tested?
New tests in
tests/client/test_streamable_http.pycover:CONNECTION_CLOSEDand the next call succeeds;The requirement test passes unmodified. The full suite passes except
test_permission_error, which fails the same way on cleanmainwhen run as root. pyright and Ruff are clean.Breaking Changes
None intended. Connect-time behaviour is unchanged.
Types of changes
Checklist
help wanted, or I'm a maintainer)Additional context
Open design point: whether the forwarded exception should reach
message_handleror only be logged.AI disclosure: I used AI assistance during the investigation and implementation. I reviewed the behavior, tests and design decisions and can explain and own the change.