Skip to content

fix(core): prevent OAuth callback timeout leak and release resources - #28678

Open
Rajeev91691 wants to merge 1 commit into
google-gemini:mainfrom
Rajeev91691:fix/oauth-callback-timeout-leak
Open

fix(core): prevent OAuth callback timeout leak and release resources#28678
Rajeev91691 wants to merge 1 commit into
google-gemini:mainfrom
Rajeev91691:fix/oauth-callback-timeout-leak

Conversation

@Rajeev91691

Copy link
Copy Markdown

Resolves #28652. Centralizes OAuth callback server settlement and resource cleanup to prevent retaining stale timeout callbacks and memory leaks.

@Rajeev91691
Rajeev91691 requested a review from a team as a code owner August 4, 2026 03:55
@github-actions github-actions Bot added the size/m A medium sized PR label Aug 4, 2026
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown

📊 PR Size: size/M

  • Lines changed: 70
  • Additions: +58
  • Deletions: -12
  • Files changed: 2

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses potential memory leaks and stale timeout callbacks in the OAuth flow by centralizing the server settlement and resource cleanup logic. By standardizing how the callback server and associated timers are terminated, the changes ensure a more robust and predictable lifecycle for OAuth operations.

Highlights

  • Resource Cleanup: Introduced a centralized cleanup function to ensure that OAuth callback servers, timers, and event listeners are properly disposed of, preventing memory leaks.
  • Timeout Management: Improved timeout handling by ensuring clearTimeout is consistently called across all exit paths, including error states and successful callbacks.
  • Test Coverage: Added new test cases to verify that timeouts are correctly cleared during both successful OAuth callbacks and state mismatch scenarios.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a centralized cleanup function in the OAuth callback server to ensure that timeouts are cleared, abort event listeners are removed, and the server is closed properly across all success and error paths. It also adds unit tests to verify timeout clearance. However, calling server.close() inside cleanup when the server is not actively listening can throw an ERR_SERVER_NOT_RUNNING error, potentially crashing the process or causing validation failures. It is recommended to guard the server close call with a check on server.listening as suggested.

Comment on lines +127 to +136
const cleanup = () => {
if (cleanedUp) return;
cleanedUp = true;
if (timeoutId) {
clearTimeout(timeoutId);
timeoutId = undefined;
}
abortController.signal.removeEventListener('abort', onAbort);
server.close();
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

critical

Calling server.close() when the server is not actively listening throws an ERR_SERVER_NOT_RUNNING error in Node.js.

This creates two critical issues in the current implementation:

  1. Process Crash on Port Collision: If server.listen() fails (e.g., EADDRINUSE), the 'error' event is emitted. The error handler calls cleanup(), which invokes server.close(). Since the server never successfully started listening, this throws ERR_SERVER_NOT_RUNNING synchronously inside the event handler, crashing the entire CLI process.
  2. Validation Failures: If OAUTH_CALLBACK_PORT is invalid, cleanup() is called before server.listen(). This throws ERR_SERVER_NOT_RUNNING synchronously, rejecting the promise with the wrong error and preventing portReject from being called, which can cause callers awaiting server.port to hang.

To fix this, guard the server.close() call by checking server.listening first.

      const cleanup = () => {
        if (cleanedUp) return;
        cleanedUp = true;
        if (timeoutId) {
          clearTimeout(timeoutId);
          timeoutId = undefined;
        }
        abortController.signal.removeEventListener('abort', onAbort);
        if (server.listening) {
          server.close();
        }
      };

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/security Issues related to security size/m A medium sized PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: OAuth callback timeout is retained after the flow completes

1 participant