langgenius / langgenius/dify

MCP client session receiver exits on orphaned responses

Open
#41,482 1 comment 1 reaction 0 assignees View on GitHub
Dominant language
TypeScript
Stars
156k
Forks
24.6k
Avg merge
22h 9m
Merged PRs (30d)
610

Description

## Description

The MCP `BaseSession` routes responses that cannot be matched to an active request through `_handle_incoming(RuntimeError(...))`. `ClientSession` uses the default message handler, which converts incoming exceptions to `ValueError`. That exception escapes `_receive_loop`, terminates the receiver future, and prevents subsequent valid MCP messages from being processed.

This affects two paths:

1. a JSON-RPC response/error whose request ID is no longer present in `_response_streams`;
2. a bare `HTTPStatusError` when there is no waiting response queue.

A late, duplicate, or otherwise orphaned response should be observable, but should not terminate the entire MCP session.

## Steps to reproduce

1. Create a `BaseSession` using a handler with the same exception behavior as `ClientSession._default_message_handler`.
2. Queue a JSON-RPC response for an unknown request ID, followed by a valid notification.
3. Run `_receive_loop()`.

The same result occurs with an unmatched `HTTPStatusError`.

## Actual behavior

Latest `main` raises and exits before processing the notification:

```text
ValueError: Server Error: SessionMessage(... JSONRPCResponse(id=999) ...)
ValueError: Received response with an unknown request ID: Unauthorized
```

The receiver logs `Error in message processing loop` and stops.

## Expected behavior

Log a warning for the orphaned response and continue processing later messages. Transport exceptions that are not orphaned responses should retain their current error behavior.

## Reproduction evidence

A test-only patch against current `main` produces two deterministic failures. A local minimal patch replacing only the two `_handle_incoming(RuntimeError(...))` calls with warning logs passes the complete BaseSession test module (`26 passed`) plus Ruff and `git diff --check`.

I can submit the focused two-file fix and regression tests if maintainers would like to assign this issue.

Contributor guide

Open the contributing guide

Research direction

Start at BaseSession._receive_loop and ClientSession._default_message_handler, then run the BaseSession test module that covers the receive loop. Reproduce both unknown-request responses and unmatched HTTPStatusError cases, and verify orphaned responses are warned about while later valid messages continue processing and other transport exceptions retain their behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend-api-design
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.