{"record":{"id":"434b8b078df233c3","repo":"google-gemini/gemini-cli","slug":"authentication-cancelled-by-user-434b8b","errorCode":null,"errorMessage":"Authentication cancelled by user.","messagePattern":"Authentication cancelled by user\\.","errorType":"exception","errorClass":"FatalCancellationError","httpStatus":null,"severity":"info","filePath":"packages/core/src/code_assist/oauth2.ts","lineNumber":319,"sourceCode":"    }\n\n    // Retrieve and cache Google Account ID after successful user code auth\n    try {\n      await fetchAndCacheUserInfo(client);\n    } catch (error) {\n      debugLogger.warn(\n        'Failed to retrieve Google Account ID during authentication:',\n        getErrorMessage(error),\n      );\n    }\n\n    await triggerPostAuthCallbacks(client.credentials);\n  } else {\n    // In ACP mode, we skip the interactive consent and directly open the browser\n    if (!config.getAcpMode()) {\n      const userConsent = await getConsentForOauth('');\n      if (!userConsent) {\n        throw new FatalCancellationError('Authentication cancelled by user.');\n      }\n    }\n\n    const webLogin = await authWithWeb(client);\n\n    coreEvents.emit(CoreEvent.UserFeedback, {\n      severity: 'info',\n      message:\n        `\\n\\nAttempting to open authentication page in your browser.\\n` +\n        `Otherwise navigate to:\\n\\n${webLogin.authUrl}\\n\\n\\n`,\n    });\n    try {\n      // Attempt to open the authentication URL in the default browser.\n      // We do not use the `wait` option here because the main script's execution\n      // is already paused by `loginCompletePromise`, which awaits the server callback.\n      const childProcess = await open(webLogin.authUrl);\n\n      // IMPORTANT: Attach an error handler to the returned child process.","sourceCodeStart":301,"sourceCodeEnd":337,"githubUrl":"https://github.com/google-gemini/gemini-cli/blob/5024443c7217464a66e98f80d73172a26440bd8f/packages/core/src/code_assist/oauth2.ts#L301-L337","documentation":"Thrown as a FatalCancellationError when getConsentForOauth('') returns a falsy value, meaning the user explicitly declined the OAuth consent prompt. This is a user-initiated cancellation, not a system error. It only fires when not in ACP mode and when browser launch is not suppressed (the interactive OAuth branch). The error allows the calling code to cleanly abort the auth flow rather than proceeding with incomplete credentials.","triggerScenarios":"In the interactive OAuth branch (browser not suppressed, not ACP mode), getConsentForOauth('') is called to ask the user for permission to start OAuth. If the user responds 'no' or cancels the prompt, it returns false and this error throws.","commonSituations":"User selects 'no' or 'cancel' at the OAuth consent prompt; the consent dialog times out; a programmatic caller sends a negative response; the user changes their mind about authenticating with Google.","solutions":["This is an expected user action — re-run the CLI and choose to authenticate when prompted.","If using a non-interactive workflow, set GEMINI_API_KEY or use ADC to avoid the consent prompt entirely.","Catch FatalCancellationError specifically in automation to exit gracefully with a clear message rather than a stack trace."],"exampleFix":"// Catching cancellation in calling code\ntry {\n  await authenticate(config);\n} catch (e) {\n  if (e instanceof FatalCancellationError) {\n    console.log('Authentication cancelled. Re-run to try again.');\n    process.exit(0);\n  }\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await getOauthClient(authType, config);\n} catch (e) {\n  if (e instanceof FatalCancellationError) {\n    console.log('Authentication cancelled by user. Re-run to authenticate.');\n    process.exit(0);\n  }\n  throw e;\n}","preventionTips":["Handle FatalCancellationError distinctly from FatalAuthenticationError.","Provide a clear 're-run to try again' message on cancellation.","In automation, skip OAuth by setting GEMINI_API_KEY to avoid consent prompts.","Use the cancellation as a signal to clean up any partial auth state."],"tags":["oauth","authentication","user-cancellation","consent","fatal"],"backgroundTag":null,"analyzedSha":"5024443c7217464a66e98f80d73172a26440bd8f","analyzedAt":"2026-08-12T06:01:53.711Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}