Skip to content

fix(cli): handle refreshAuth rejection in non-interactive prompt path#26932

Open
Eswar809 wants to merge 1 commit into
google-gemini:mainfrom
Eswar809:fix/unhandled-promise-rejection-25739
Open

fix(cli): handle refreshAuth rejection in non-interactive prompt path#26932
Eswar809 wants to merge 1 commit into
google-gemini:mainfrom
Eswar809:fix/unhandled-promise-rejection-25739

Conversation

@Eswar809
Copy link
Copy Markdown
Contributor

Summary

The second refreshAuth call inside main()'s non-interactive prompt flow ran unguarded, so a transient network error during OAuth token refresh or the
experiments fetch (e.g. ECONNRESET against cloudcode-pa.googleapis.com) surfaced as an unhandled promise rejection and crashed the CLI before any
user-facing message could be printed.

Wrap the call in a try/catch that reports the error to stderr, logs the full detail via debugLogger, and exits with FATAL_AUTHENTICATION_ERROR after
running the registered cleanup hooks — matching the existing pattern used by the earlier pre-sandbox refreshAuth attempt.

Fixes #25739

Test plan

  • New test "should exit with FATAL_AUTHENTICATION_ERROR when refreshAuth rejects in non-interactive mode" passes — asserts exit code, that
    runNonInteractive is not reached, and that refreshAuth was called with the resolved auth type
  • 41/44 gemini.test.tsx pass (2 pre-existing timeouts unrelated to this change reproduce on main without the fix)
  • npm run preflight exit 0

The second refreshAuth call inside main()'s non-interactive prompt flow ran
unguarded, so a transient network error during OAuth token refresh or the
experiments fetch (e.g. ECONNRESET against cloudcode-pa.googleapis.com)
surfaced as an unhandled promise rejection and crashed the CLI before any
user-facing message could be printed.

Wrap the call in a try/catch that reports the error to stderr, logs the full
detail via debugLogger, and exits with FATAL_AUTHENTICATION_ERROR after
running the registered cleanup hooks, matching the existing pattern used by
the earlier pre-sandbox refreshAuth attempt.

Fixes google-gemini#25739
@Eswar809 Eswar809 requested a review from a team as a code owner May 12, 2026 18:02
@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 a stability issue in the CLI where transient network errors during the non-interactive authentication flow caused the process to crash ungracefully. By introducing robust error handling, the CLI now catches these failures, logs them appropriately, and performs necessary cleanup before exiting, improving the overall user experience and debuggability.

Highlights

  • Error Handling: Wrapped the refreshAuth call in the non-interactive flow with a try/catch block to prevent unhandled promise rejections during network errors.
  • Graceful Exit: Implemented proper error reporting to stderr and cleanup hook execution before exiting with FATAL_AUTHENTICATION_ERROR when authentication fails.
  • Testing: Added a new test case to verify that the CLI exits with the correct error code and skips subsequent execution when refreshAuth fails.
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.

Copy link
Copy Markdown
Contributor

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

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 error handling for authentication refreshes in non-interactive mode within the Gemini CLI. Specifically, it wraps the refreshAuth call in a try-catch block to surface network or authentication errors (like ECONNRESET) as fatal errors instead of allowing them to cause unhandled crashes. A corresponding test case was added to verify this behavior. Feedback was provided regarding the test implementation, recommending the use of vi.stubEnv() for environment variable manipulation to align with the project's style guide and improve test reliability.

Comment on lines +1464 to +1475
process.env['GEMINI_API_KEY'] = 'test-key';
try {
await main();
expect.fail('Should have thrown MockProcessExitError');
} catch (e) {
expect(e).toBeInstanceOf(MockProcessExitError);
expect((e as MockProcessExitError).code).toBe(
ExitCodes.FATAL_AUTHENTICATION_ERROR,
);
} finally {
delete process.env['GEMINI_API_KEY'];
}
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.

high

The repository style guide recommends using vi.stubEnv() instead of modifying process.env directly in tests to prevent test leakage and improve reliability. Since afterEach in this file already calls vi.unstubAllEnvs(), you can also remove the manual cleanup in the finally block.

    vi.stubEnv('GEMINI_API_KEY', 'test-key');
    try {
      await main();
      expect.fail('Should have thrown MockProcessExitError');
    } catch (e) {
      expect(e).toBeInstanceOf(MockProcessExitError);
      expect((e as MockProcessExitError).code).toBe(
        ExitCodes.FATAL_AUTHENTICATION_ERROR,
      );
    }
References
  1. Avoid modifying process.env directly; use vi.stubEnv instead. (link)

@gemini-cli gemini-cli Bot added priority/p1 Important and should be addressed in the near term. area/core Issues related to User Interface, OS Support, Core Functionality labels May 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/core Issues related to User Interface, OS Support, Core Functionality priority/p1 Important and should be addressed in the near term.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CRITICAL: Unhandled Promise Rejection!

1 participant