Fix ObjectDisposedException by awaiting handler tasks before session disposal#1401
Open
Varun6578 wants to merge 1 commit intomodelcontextprotocol:mainfrom
Open
Conversation
…disposal Track fire-and-forget message handler tasks in ProcessMessagesCoreAsync and await them in the finally block. This ensures that when the message processing task completes (e.g., due to cancellation), all outstanding handler tasks have finished before the method returns. Since McpSessionHandler.DisposeAsync awaits the message processing task, this guarantees that service scopes are not disposed while handlers are still executing. This fixes an issue in stateless HTTP mode where ASP.NET Core disposes the request service scope after the message processing task completes, but previously fire-and-forget handler tasks could still be running, causing ObjectDisposedException when they try to resolve scoped services. Fixes modelcontextprotocol#1269 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #1269
When using HTTP transport with
Stateless = true, if the client closes the connection (e.g., OpenAI times out on a long-running tool), the ASP.NET Core request scope is disposed while tool handlers are still executing, causingObjectDisposedException.Root Cause
In
McpSessionHandler.ProcessMessagesCoreAsync(), message handlers were launched as fire-and-forget tasks (_ = ProcessMessageAsync()). These tasks were not tracked or awaited.When
McpSessionHandler.DisposeAsync()cancelled the message processing CTS and awaited_messageProcessingTask, the channel reader loop exited immediately but the fire-and-forget handler tasks continued running. The session disposal then completed, ASP.NET Core disposed the request service scope, and the still-running handlers gotObjectDisposedExceptionwhen resolving scoped services.Fix
List<Task>instead of discarding themawait Task.WhenAll(pendingHandlerTasks)in thefinallyblock ofProcessMessagesCoreAsyncbefore the method returnsTest Results