Skip to content

Comments

Fix off-by-one error in reconnection attempts#1356

Merged
stephentoub merged 4 commits intomainfrom
copilot/fix-off-by-one-error
Feb 23, 2026
Merged

Fix off-by-one error in reconnection attempts#1356
stephentoub merged 4 commits intomainfrom
copilot/fix-off-by-one-error

Conversation

Copy link
Contributor

Copilot AI commented Feb 22, 2026

  • Investigate off-by-one error in SendGetSseRequestWithRetriesAsync retry loop
  • Fix: initialize attempt = -1 when state.LastEventId is null (initial connection case in ReceiveUnsolicitedMessagesAsync)
  • Build and test (all tests pass; pre-existing auth conformance failures on net8.0 are unrelated)
  • Add unit test verifying the initial GET SSE connection doesn't consume a reconnection slot
  • Fix net472 build: use TaskCompletionSource<bool> instead of non-generic TaskCompletionSource
  • Code review (no issues found)

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI self-assigned this Feb 22, 2026
…n loop

When ReceiveUnsolicitedMessagesAsync calls SendGetSseRequestWithRetriesAsync,
the first attempt is an initial GET SSE connection (not a reconnection).
Previously, this initial attempt was counted against MaxReconnectionAttempts,
meaning with the default value of 2, only 1 actual reconnection was made.

Fix: initialize attempt = -1 when LastEventId is null (initial connection),
so the initial attempt doesn't consume a reconnection slot. When LastEventId
is set (pure reconnection from POST SSE resume), attempt starts at 0 as before.

Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
@stephentoub stephentoub added this to the 1.0.0 (GA) milestone Feb 22, 2026
…axReconnectionAttempts

Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
Copilot AI requested a review from stephentoub February 22, 2026 02:51
@stephentoub stephentoub changed the title [WIP] Fix off-by-one error in reconnection attempts Fix off-by-one error in reconnection attempts Feb 22, 2026
@stephentoub stephentoub marked this pull request as ready for review February 22, 2026 03:44
@stephentoub stephentoub requested a review from halter73 February 22, 2026 03:44
@stephentoub
Copy link
Contributor

@copilot there are build failures

…ic TaskCompletionSource

Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 22, 2026

@copilot there are build failures

Fixed in 1f850f0. The non-generic TaskCompletionSource isn't available on net472 — changed to TaskCompletionSource<bool> to match the pattern used elsewhere in the test project.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request fixes an off-by-one error in the SSE (Server-Sent Events) reconnection retry logic for the Streamable HTTP client transport. The bug caused the initial GET SSE connection to be incorrectly counted as a reconnection attempt, effectively reducing the configured MaxReconnectionAttempts by one.

Changes:

  • Fixed the retry counter initialization to distinguish initial connections from reconnections
  • Added comprehensive test coverage to verify the fix
  • Ensured .NET Framework compatibility using generic TaskCompletionSource<bool>

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/ModelContextProtocol.Core/Client/StreamableHttpClientSessionTransport.cs Fixed off-by-one error by initializing attempt = -1 for initial connections (when LastEventId is null) and attempt = 0 for reconnections (when LastEventId is set), with clear inline comments explaining the logic
tests/ModelContextProtocol.Tests/Transport/HttpClientTransportTests.cs Added test StreamableHttp_InitialGetSseConnection_DoesNotCountAgainstMaxReconnectionAttempts that verifies the initial connection plus configured reconnection attempts equals the total number of GET requests, and added System.Text import for test setup

@stephentoub stephentoub merged commit 2c9bb5d into main Feb 23, 2026
14 checks passed
@stephentoub stephentoub deleted the copilot/fix-off-by-one-error branch February 23, 2026 16:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants