{"record":{"id":"e45b62d12414aa29","repo":"google-gemini/gemini-cli","slug":"failed-to-clear-oauth-credentials","errorCode":null,"errorMessage":"Failed to clear OAuth credentials","messagePattern":"Failed to clear OAuth credentials","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"packages/core/src/code_assist/oauth-credential-storage.ts","lineNumber":105,"sourceCode":"  }\n\n  /**\n   * Clear cached OAuth credentials\n   */\n  static async clearCredentials(): Promise<void> {\n    try {\n      await this.storage.deleteCredentials(MAIN_ACCOUNT_KEY);\n\n      // Also try to remove the old file if it exists\n      const oldFilePath = path.join(homedir(), GEMINI_DIR, OAUTH_FILE);\n      await fs.rm(oldFilePath, { force: true }).catch(() => {});\n    } catch (error: unknown) {\n      coreEvents.emitFeedback(\n        'error',\n        'Failed to clear OAuth credentials',\n        error,\n      );\n      throw new Error('Failed to clear OAuth credentials', { cause: error });\n    }\n  }\n\n  /**\n   * Migrate credentials from old file-based storage to keychain\n   */\n  private static async migrateFromFileStorage(): Promise<Credentials | null> {\n    const oldFilePath = path.join(homedir(), GEMINI_DIR, OAUTH_FILE);\n\n    let credsJson: string;\n    try {\n      credsJson = await fs.readFile(oldFilePath, 'utf-8');\n    } catch (error: unknown) {\n      if (\n        typeof error === 'object' &&\n        error !== null &&\n        'code' in error &&\n        error.code === 'ENOENT'","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/google-gemini/gemini-cli/blob/5024443c7217464a66e98f80d73172a26440bd8f/packages/core/src/code_assist/oauth-credential-storage.ts#L87-L123","documentation":"Thrown by OAuthCredentialStorage.clearCredentials() when the underlying HybridTokenStorage fails to delete the stored credentials. The method attempts to delete from keychain storage and also removes the legacy file at ~/.gemini/oauth_creds.json (best-effort, errors ignored). If the primary storage.deleteCredentials() call throws, the error is wrapped with cause and re-thrown, blocking the logout/clear operation.","triggerScenarios":"Calling OAuthCredentialStorage.clearCredentials() when storage.deleteCredentials('main-account') throws — typically a keychain access error, a locked keychain, or a missing secret-service daemon.","commonSituations":"User attempts to log out but the OS keychain is locked (macOS) or secret-service is unavailable (Linux headless/CI); permission changes revoked the application's keychain access; the keychain backend changed between sessions (e.g., switching desktop environments); running in a sandboxed environment that blocks keychain writes.","solutions":["On macOS, unlock the login keychain before clearing.","On Linux, ensure gnome-keyring/seahorse is running and accessible.","Manually remove the credentials: delete the ~/.gemini/oauth_creds.json file and the keychain entry for 'gemini-cli-oauth / main-account'.","In environments where keychain is unavailable, set up a file-based token storage backend or use API key auth instead.","Inspect error.cause for the specific backend error."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await OAuthCredentialStorage.clearCredentials();\n} catch (e) {\n  if (e instanceof Error && e.message === 'Failed to clear OAuth credentials') {\n    // Best-effort: manually remove the legacy file\n    await fs.rm(path.join(homedir(), '.gemini', OAUTH_FILE), { force: true }).catch(() => {});\n    console.warn('Could not clear keychain entry. Remove it manually from your OS keychain.');\n  } else throw e;\n}","preventionTips":["Ensure keychain access before relying on clearCredentials in automation.","Provide a manual fallback (file deletion) in calling code.","Test clearCredentials in the target environment before deployment.","Document the keychain service name ('gemini-cli-oauth') for manual removal."],"tags":["oauth","credentials","keychain","storage","logout"],"backgroundTag":null,"analyzedSha":"5024443c7217464a66e98f80d73172a26440bd8f","analyzedAt":"2026-08-12T06:01:53.711Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}