fix(client): treat any 2xx as successful session termination - #3548
deadczarvc wants to merge 1 commit into
Conversation
Streamable HTTP DELETE termination warned 'Session termination failed: 202' for spec-compliant asynchronous deletes. HTTP semantics make any 2xx a success; the Streamable HTTP spec only carves out 405 for this request. Accept the whole 2xx range and keep the warning for genuine failures. Fixes modelcontextprotocol#3546
|
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 #3546. If a maintainer assigns you to #3546, 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 |
|
Pushed c725630 addressing the CI coverage failures (tests themselves were green everywhere): 1. Line 677 ( 2. Coverage 99.99 < fail-under=100 on Python 3.14 (both The only missing coverage was two partial branches inside the new test itself — the Local verification (Python 3.13 venv): Note: the PR remains closed pending maintainer assignment to #3546 — pushing anyway per the bot's guidance so the fix is review-ready if the PR is reopened. |
Fixes #3546.
Problem
terminate_sessioninsrc/mcp/client/streamable_http.pytreats anyDELETEresponse outside(200, 204)as a failure and logsSession termination failed: 202.202 Acceptedis the correct response for a server that processes termination asynchronously; under HTTP semantics any 2xx is success, and the Streamable HTTP spec only carves out405for this request.In a long-running Hermes Agent deployment with several Streamable HTTP MCP servers this produced 72 spurious warnings in ~36 hours in
errors.log, burying real failures that surface through the same line.Change
One condition:
elif not 200 <= response.status_code < 300:. The 405 debug path and the warning for genuine failures (4xx/5xx) are unchanged.Testing
Added
test_streamable_http_client_session_termination_status_handlingnext to the existing termination tests intests/shared/test_streamable_http.py, reusing theAnswerDeleteWith204wrapping-transport pattern: parametrized over202(no warning logged) and500(warning still logged). Verified red on unmodifiedmainfor the 202 case, green after the fix.tests/shared/test_streamable_http.py: 75 passedruff check/ruff format --check: cleanpyrighton the touched module: 0 errorsFull suite not run locally (Windows env); CI will cover the rest.