fix(auth): release lock around yield in async_auth_flow to prevent RuntimeError #2026
+84
−55
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.
Bug Summary
Error:
RuntimeError: The current task is not holding this lockLocation:
src/mcp/client/auth/oauth2.py-OAuthClientProvider.async_auth_flow()Impact: OAuth authentication fails when the browser opens for authorization
Root Cause
The
async_auth_flow()method wraps all yield statements inside a singleasync with self.context.lock:block. When the async generator suspends atyield, the event loop may switch tasks, andanyio.Lock(which tracks task ownership) raisesRuntimeErrorwhen the generator resumes or is garbage-collected in a different task context.Solution
Release the lock before each
yieldand re-acquire it after the generator resumes:yield(generator suspension point)yieldresumesAll existing functionality is preserved:
Test Results
All existing tests pass (166 passed, 0 failed):
``````
$ pytest tests/client/ -x -q
166 passed, 3 skipped, 1 xfailed
``````
Reproduction
RuntimeError: The current task is not holding this lock