Skip to content

fix(gemini): session expired#363

Merged
robinebers merged 2 commits into
robinebers:mainfrom
yhunko:main
Apr 12, 2026
Merged

fix(gemini): session expired#363
robinebers merged 2 commits into
robinebers:mainfrom
yhunko:main

Conversation

@yhunko
Copy link
Copy Markdown
Contributor

@yhunko yhunko commented Apr 8, 2026

Description

Fixes Gemini session expired issue

Related Issue

Fixes #357

Type of Change

  • Bug fix
  • New feature
  • New provider plugin
  • Documentation
  • Performance improvement
  • Other (describe below)

Testing

  • I ran bun run build and it succeeded
  • I ran bun run test and all tests pass
  • I tested the change locally with bun tauri dev

Checklist

  • I read CONTRIBUTING.md
  • My PR targets the main branch
  • I did not introduce new dependencies without justification

Summary by cubic

Fixes Gemini “session expired” by reliably finding OAuth client credentials and refreshing tokens across common install paths. Adds clear warnings when none are found; fixes #357.

  • Bug Fixes
    • Dynamically scans for @google/gemini-cli-core/@google/gemini-cli oauth2.js in flat and nested layouts (NVM, FNM with corrected ~/Library/Application Support/fnm/.../installation path, Volta, npm/pnpm globals, Homebrew, /usr/local).
    • Refreshes tokens with discovered client ID/secret and persists to ~/.gemini/oauth_creds.json.
    • Logs a single warning when OAuth creds are not found; read errors include the file path.

Written for commit 7735d12. Summary will update on new commits.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

No issues found across 2 files

@validatedev validatedev requested a review from Copilot April 8, 2026 22:56
@validatedev
Copy link
Copy Markdown
Collaborator

@codex review

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes recurring Gemini “session expired” failures by improving how the plugin discovers the Gemini CLI OAuth client credentials (oauth2.js) across common global install/version-manager layouts, enabling token refresh to succeed more reliably.

Changes:

  • Replace the static oauth2.js path list with dynamic candidate path generation (static roots + nested layouts + NVM/FNM scanning + Volta paths).
  • Improve logging to include the failing oauth2.js path when a read/parse attempt errors, and warn when no credentials can be found.
  • Add test coverage for NVM version scanning discovery, nested dependency layouts, and the “no oauth2.js found” warning behavior.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
plugins/gemini/plugin.js Dynamically builds candidate oauth2.js paths (including version-manager scanning) and improves warning logs when credentials cannot be read/found.
plugins/gemini/plugin.test.js Adds tests validating the new discovery strategies and warning behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread plugins/gemini/plugin.js
Comment on lines 128 to 141
function loadOauthClientCreds(ctx) {
for (let i = 0; i < OAUTH2_JS_PATHS.length; i += 1) {
const path = OAUTH2_JS_PATHS[i]
const candidates = buildOauthCandidatePaths(ctx)
for (let i = 0; i < candidates.length; i += 1) {
const path = candidates[i]
if (!ctx.host.fs.exists(path)) continue
try {
const parsed = parseOauthClientCreds(ctx.host.fs.readText(path))
if (parsed) return parsed
} catch (e) {
ctx.host.log.warn("failed reading oauth2.js: " + String(e))
ctx.host.log.warn("failed reading oauth2.js at " + path + ": " + String(e))
}
}
ctx.host.log.warn("Gemini OAuth client credentials not found in any known install path")
return null
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

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

loadOauthClientCreds logs a warning every time no oauth2.js match is found. Since refreshToken() can be invoked multiple times in a single probe() (initial refresh + retryOnceOnAuth for loadCodeAssist + quota), this can emit the same warning multiple times per probe and spam logs. Consider memoizing the “not found” result (e.g., module-scoped warnedMissingOauth2 flag) and/or caching the resolved client creds so the warning is emitted at most once per process/session.

Copilot uses AI. Check for mistakes.
Comment thread plugins/gemini/plugin.js
Comment on lines +32 to +58
function buildOauthCandidatePaths(ctx) {
var paths = []

for (var i = 0; i < STATIC_MODULE_ROOTS.length; i += 1) {
paths.push(STATIC_MODULE_ROOTS[i] + OAUTH2_SUFFIX_FLAT)
paths.push(STATIC_MODULE_ROOTS[i] + OAUTH2_SUFFIX_NESTED)
}

for (var i = 0; i < STATIC_NESTED_ONLY.length; i += 1) {
paths.push(STATIC_NESTED_ONLY[i] + OAUTH2_SUFFIX_NESTED)
}

for (var i = 0; i < VERSION_MANAGER_ROOTS.length; i += 1) {
var root = VERSION_MANAGER_ROOTS[i]
var versions = listDirSafe(ctx, root)
for (var j = 0; j < versions.length; j += 1) {
var base = root + "/" + versions[j] + "/lib/node_modules"
paths.push(base + OAUTH2_SUFFIX_FLAT)
paths.push(base + OAUTH2_SUFFIX_NESTED)
}
}

// volta stores packages differently
paths.push("~/.volta/tools/image/packages/@google/gemini-cli/lib/node_modules" + OAUTH2_SUFFIX_NESTED)
paths.push("~/.volta/tools/image/packages/@google/gemini-cli/lib/node_modules" + OAUTH2_SUFFIX_FLAT)

return paths
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

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

buildOauthCandidatePaths() does directory listings and builds a potentially large candidate list on every call to loadOauthClientCreds(). Because refresh may be attempted multiple times per probe() (and probes may run frequently), this can lead to repeated filesystem work. Consider caching the computed candidate paths and/or caching the parsed OAuth client credentials after the first successful read to avoid rescanning on subsequent refresh attempts.

Copilot uses AI. Check for mistakes.
@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Bravo.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@validatedev
Copy link
Copy Markdown
Collaborator

@yhunko please resolve the conversations and we can continue after that. thanks!

@robinebers robinebers merged commit 60cc426 into robinebers:main Apr 12, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Gemini] Session expired way too often

4 participants