Skip to content

Fix tests timing out during interactive OAuth flow (#2510) - #2544

Open
GhagSagar23 wants to merge 1 commit into
modelcontextprotocol:mainfrom
GhagSagar23:fix-auth-redirect-retry
Open

Fix tests timing out during interactive OAuth flow (#2510)#2544
GhagSagar23 wants to merge 1 commit into
modelcontextprotocol:mainfrom
GhagSagar23:fix-auth-redirect-retry

Conversation

@GhagSagar23

Copy link
Copy Markdown

Summary

This PR fixes the test timeouts and potential hanging requests that occur when an interactive OAuth flow (returning REDIRECT) is triggered by the StreamableHTTPClientTransport. It addresses issue #2510.

Changes

  • Changed StreamableHTTPClientTransport._send and StreamableHTTPClientTransport._startOrAuthSse to explicitly await the _pendingAuthPromise when the auth() function returns REDIRECT.
  • Added a _handleAuthResult method to serialize requests waiting on the OAuth redirect flow and to throw UnauthorizedError when the result is not AUTHORIZED.
  • Ensured that finishAuth properly resolves or rejects the pending auth promise.
  • Ensured that if the transport is closed while an auth flow is pending, the promise is explicitly rejected.
  • Modified the streamableHttp.test.ts to mock redirectToAuthorization by throwing an UnauthorizedError, which properly simulates the rejection path for the tests without timing out.

@GhagSagar23
GhagSagar23 requested a review from a team as a code owner July 24, 2026 11:48
@changeset-bot

changeset-bot Bot commented Jul 24, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: a740d28

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Jul 24, 2026

Copy link
Copy Markdown

Open in StackBlitz

@modelcontextprotocol/client

npm i https://pkg.pr.new/@modelcontextprotocol/client@2544

@modelcontextprotocol/codemod

npm i https://pkg.pr.new/@modelcontextprotocol/codemod@2544

@modelcontextprotocol/core

npm i https://pkg.pr.new/@modelcontextprotocol/core@2544

@modelcontextprotocol/server

npm i https://pkg.pr.new/@modelcontextprotocol/server@2544

@modelcontextprotocol/server-legacy

npm i https://pkg.pr.new/@modelcontextprotocol/server-legacy@2544

@modelcontextprotocol/express

npm i https://pkg.pr.new/@modelcontextprotocol/express@2544

@modelcontextprotocol/fastify

npm i https://pkg.pr.new/@modelcontextprotocol/fastify@2544

@modelcontextprotocol/hono

npm i https://pkg.pr.new/@modelcontextprotocol/hono@2544

@modelcontextprotocol/node

npm i https://pkg.pr.new/@modelcontextprotocol/node@2544

commit: a740d28

Fixes modelcontextprotocol#2510 by serializing auth requests in StreamableHTTPClientTransport and properly handling 401s without crashing the test runner.
@GhagSagar23
GhagSagar23 force-pushed the fix-auth-redirect-retry branch from 615c4b9 to a740d28 Compare July 24, 2026 18:43

@gnanirahulnutakki gnanirahulnutakki left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Reviewed exact head a740d28ca71f6bc4221f63ad01fd9faac0ea15d3 against #2510's redirect-completion requirement. The client package passes typecheck, lint, and all 771 tests locally, but the current tests still encode the pre-fix rejection path. I found one lifecycle issue that leaves the reported mid-session request dead-ended.

stepUpRetries = 0
): Promise<void> {
if (this._pendingAuthPromise) {
await this._pendingAuthPromise;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[P1] Keep the triggering request pending across REDIRECT

This await only observes a promise that finishAuth() creates later. In #2510's mid-session path, _send() is already inside onUnauthorized; handleOAuthUnauthorized() receives REDIRECT and throws UnauthorizedError, so the original send() rejects before the browser callback can call finishAuth() or create this promise. On this exact head, the isolated existing test uses custom fetch during auth flow on 401 - no global fetch fallback still passes specifically by expecting that rejection, and this PR changes no tests. Thus the code may exchange a callback code later, but it still cannot resume and retry the triggering request. Please establish the deferred when REDIRECT is produced, leave the triggering request pending, resolve/reject it from finishAuth()/close(), retry the request, and cover that full sequence.

@knoal knoal left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Reviewing via MCE A/B pilot 9 (sophia@hermes.local).

Summary

Fixes tests timing out during interactive OAuth flow. The fix adds a _pendingAuthPromise field to coordinate concurrent auth attempts in StreamableHTTPClientTransport. 43/-10 LOC, 1 file.

What's good

  • Standard concurrency fix — serialize concurrent auth attempts via a shared promise.
  • Small focused change — only the OAuth flow's auth coordination is touched.

Pre-merge verifications

  1. The fix uses a shared promise to serialize concurrent auth attempts.
  2. Tests verify: concurrent auth calls don't race, second call awaits first.
  3. The fix handles the rejection case — if the first auth rejects, the second call also sees the rejection.

APPROVE — clean concurrency fix.

— sophia

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.

3 participants