{"record":{"id":"2fa3eebfbcb8a74f","repo":"google-gemini/gemini-cli","slug":"manual-authorization-is-required-but-the-current-s","errorCode":null,"errorMessage":"Manual authorization is required but the current session is non-interactive. Please run the Gemini CLI in an interactive terminal to log in, provide a GEMINI_API_KEY, or ensure Application Default Credentials are configured.","messagePattern":"Manual authorization is required but the current session is non-interactive\\. Please run the Gemini CLI in an interactive terminal to log in, provide a GEMINI_API_KEY, or ensure Application Default Credentials are configured\\.","errorType":"exception","errorClass":"FatalAuthenticationError","httpStatus":null,"severity":"critical","filePath":"packages/core/src/code_assist/oauth2.ts","lineNumber":262,"sourceCode":"        // the service account email.\n      });\n      await computeClient.getAccessToken();\n      debugLogger.log('Authentication successful.');\n\n      // Do not cache creds in this case; note that Compute client will handle its own refresh\n      return computeClient;\n    } catch (e) {\n      throw new Error(\n        `Could not authenticate using metadata server application default credentials. Please select a different authentication method or ensure you are in a properly configured environment. Error: ${getErrorMessage(\n          e,\n        )}`,\n      );\n    }\n  }\n\n  if (config.isBrowserLaunchSuppressed()) {\n    if (!config.isInteractive()) {\n      throw new FatalAuthenticationError(\n        'Manual authorization is required but the current session is non-interactive. ' +\n          'Please run the Gemini CLI in an interactive terminal to log in, ' +\n          'provide a GEMINI_API_KEY, or ensure Application Default Credentials are configured.',\n      );\n    }\n    let success = false;\n    const maxRetries = 2;\n    // Enter alternate buffer\n    enterAlternateScreen();\n    // Clear screen and move cursor to top-left.\n    writeToStdout('\\u001B[2J\\u001B[H');\n    disableMouseEvents();\n    disableKittyKeyboardProtocol();\n    enableLineWrapping();\n\n    try {\n      for (let i = 0; !success && i < maxRetries; i++) {\n        success = await authWithUserCode(client);","sourceCodeStart":244,"sourceCodeEnd":280,"githubUrl":"https://github.com/google-gemini/gemini-cli/blob/5024443c7217464a66e98f80d73172a26440bd8f/packages/core/src/code_assist/oauth2.ts#L244-L280","documentation":"Thrown as a FatalAuthenticationError when browser launch is suppressed (NO_BROWSER=true or equivalent) AND the current session is non-interactive (no TTY). In this state the OAuth flow requires manual authorization (the user must open a URL and paste a code), but there is no terminal to display the prompt. The error lists three alternative auth methods: run interactively, set GEMINI_API_KEY, or configure Application Default Credentials.","triggerScenarios":"config.isBrowserLaunchSuppressed() returns true (NO_BROWSER env var set) and config.isInteractive() returns false (stdin is not a TTY). The code checks both conditions before attempting the user-code auth flow and throws immediately since the flow cannot proceed.","commonSituations":"Running the CLI in a CI/CD pipeline, Docker container, SSH session without TTY allocation, or cron job where NO_BROWSER is set and there's no interactive terminal; a headless server deployment; piping stdin from another process making the session non-interactive.","solutions":["Set GEMINI_API_KEY environment variable for non-interactive, non-browser authentication.","Configure Application Default Credentials: run 'gcloud auth application-default login' on a machine with a browser, then copy the credentials.","Run the CLI in an interactive terminal with a TTY and without NO_BROWSER set to complete OAuth once.","If in a container, use 'docker run -it' to allocate a TTY."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Pre-flight check: can we authenticate in this environment?\nfunction canAuthenticateNonInteractively(config: Config): boolean {\n  if (process.env['GEMINI_API_KEY']) return true;\n  // Check for ADC file existence\n  const adcPath = path.join(process.env['CLOUDSDK_CONFIG'] ?? path.join(homedir(), '.config', 'gcloud'), 'application_default_credentials.json');\n  return fsSync.existsSync(adcPath);\n}\n\nif (config.isBrowserLaunchSuppressed() && !config.isInteractive()) {\n  if (!canAuthenticateNonInteractively(config)) {\n    throw new Error('Non-interactive session needs GEMINI_API_KEY or ADC configured.');\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  client = await getOauthClient(authType, config);\n} catch (e) {\n  if (e instanceof FatalAuthenticationError && e.message.includes('non-interactive')) {\n    // Provide guidance and exit gracefully\n    console.error('Set GEMINI_API_KEY or run in an interactive terminal.');\n    process.exit(2);\n  }\n  throw e;\n}","preventionTips":["Always set GEMINI_API_KEY in CI/CD and headless environments.","Run 'gcloud auth application-default login' once on a machine with a browser.","Use 'docker run -it' to allocate a TTY for interactive OAuth in containers.","Detect non-interactive environments early and switch auth strategy."],"tags":["oauth","authentication","non-interactive","environment","fatal"],"backgroundTag":null,"analyzedSha":"5024443c7217464a66e98f80d73172a26440bd8f","analyzedAt":"2026-08-12T06:01:53.711Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}