Skip to content

fix(core): pass resumed session data through config init to avoid orphan session file - #29206

Closed
chelsealong wants to merge 1 commit into
google-gemini:mainfrom
chelsealong:fix/29198-resume-session-second-file
Closed

fix(core): pass resumed session data through config init to avoid orphan session file#29206
chelsealong wants to merge 1 commit into
google-gemini:mainfrom
chelsealong:fix/29198-resume-session-second-file

Conversation

@chelsealong

Copy link
Copy Markdown

The bug

gemini --resume <uuid> reuses the resumed session's id for the process
(resolveSessionId returns sessionData.sessionId). But config.initialize()
starts the Gemini client with no resumed session data:

await this._geminiClient.initialize();

GeminiClient.initialize()GeminiChat.initialize(undefined) then takes the
"create new session" branch in ChatRecordingService, opening a second
JSONL file:

session-<UTC minute>-<session id[0:8]>.jsonl

Because the process id is the resumed session's real id, this orphan file
carries the same eight-character suffix as the real conversation file, and
holds nothing but an initial metadata line — the recorder never uses it, since
useSessionResume's resumeChat() call (which does receive the resumed data
and correctly reopens the real file) only runs later, in a React effect.

That empty orphan is never cleaned up on its own exit path, either — cleanup
only runs against config.getGeminiClient().getChatRecordingService(), which
after resumeChat() completes points at the real file, not the orphan.
The orphan is what a later startup's session-retention sweep finds:
hasResumableContent is false for it, so it is treated as corrupted, and
cleanup derives the short id from its filename and expands the deletion to
every file ending in that same -<shortId>.jsonl — including the real
conversation. That's exactly what's reported in #29198: after resuming a
session and exiting without interacting, trying to resume the same session
again later shows it gone from --list-sessions and --resume <uuid> fails.

The fix

Thread resumedSessionData through the one call site that was dropping it:

config.initialize(resumedSessionData)
  -> GeminiClient.initialize(resumedSessionData)
    -> startChat(undefined, resumedSessionData)
      -> GeminiChat.initialize(resumedSessionData)
        -> ChatRecordingService reopens the existing file instead of creating a new one
  • packages/core/src/config/config.ts: initialize()/_initialize() accept
    and forward resumedSessionData to this._geminiClient.initialize(...).
  • packages/core/src/core/client.ts: GeminiClient.initialize() accepts
    resumedSessionData and passes it to startChat().
  • packages/cli/src/gemini.tsx and packages/cli/src/ui/AppContainer.tsx:
    the two call sites of config.initialize() (non-interactive and interactive
    paths) now pass the resumedSessionData they already have in scope.

History is untouched by this change — startChat(undefined, resumedSessionData)
still passes no extraHistory, so the in-memory chat history continues to be
built exclusively by the later resumeChat() call in useSessionResume. This
change only fixes which file chat recording targets from the start.

Test plan

Added a regression test in packages/core/src/core/client.test.ts asserting
that GeminiClient.initialize(resumedSessionData) forwards the data to
startChat. Verified it fails without the fix:

$ git checkout HEAD~1 -- packages/core/src/core/client.ts
$ npm test --workspace @google/gemini-cli-core -- src/core/client.test.ts -t initialize
 FAIL  src/core/client.test.ts > Gemini Client (client.ts) > initialize > passes resumed session data to startChat so recording reopens the existing file
 AssertionError: expected "startChat" to be called with arguments: [ undefined, …(1) ]
 Received: [[]]  (called with no resumedSessionData)
$ git checkout HEAD -- packages/core/src/core/client.ts

With the fix, the full targeted suites pass:

$ npm test --workspace @google/gemini-cli-core -- src/core/client.test.ts src/config/config.test.ts src/services/chatRecordingService.test.ts src/core/geminiChat.test.ts
 Test Files  4 passed (4)
      Tests  480 passed | 1 skipped (481)

$ npm test --workspace @google/gemini-cli -- src/ui/AppContainer.test.tsx
 Test Files  1 passed (1)
      Tests  112 passed (112)

src/gemini.test.tsx has 9 pre-existing failures (FatalUntrustedWorkspaceError: Gemini CLI is not running in a trusted directory) that reproduce identically
on unmodified main in this sandbox — unrelated to this change (headless/CI
trusted-folder detection in the test environment).

npx eslint and npx prettier --check are clean on all changed files, and
npm run typecheck passes across all workspaces.

Fixes #29198.


This PR was prepared with AI assistance (an autonomous coding agent
investigated the issue, traced the root cause, wrote the fix, and verified it
with the tests above). A human reviewed the change before submission.

…han session file

config.initialize() started the Gemini client with no resumed session
data even when the process was launched via --resume, so chat
recording treated the resume as a brand new conversation and opened a
second, empty session file. Because the process reuses the resumed
session's id, that empty file shares the same eight-character id
suffix as the real conversation file. Startup retention cleanup
expands deletion of a non-resumable file to every file sharing that
suffix, wiping out the real session on a later launch.

Thread resumedSessionData through config.initialize() ->
GeminiClient.initialize() -> startChat() so chat recording reopens the
existing file from the start.
@chelsealong
chelsealong requested a review from a team as a code owner September 4, 2026 08:04
@github-actions github-actions Bot added the size/m A medium sized PR label Sep 4, 2026
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

You already have 7 pull requests open. Please work on getting existing PRs merged before opening more.

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

📊 PR Size: size/M

  • Lines changed: 57
  • Additions: +49
  • Deletions: -8
  • Files changed: 5

@github-actions github-actions Bot closed this Sep 4, 2026
@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 critical issue where resuming a Gemini session would inadvertently create an orphaned, empty chat file. Because this orphan shared the same session ID suffix as the real conversation file, the system's automated session-retention cleanup would incorrectly identify the real conversation as corrupted and delete it. By ensuring the resumed session data is passed through the initialization chain, the application now correctly reopens the existing session file instead of creating a new one.

Highlights

  • Session Data Propagation: Updated the configuration initialization flow to thread resumedSessionData through to the Gemini client, ensuring that resumed sessions correctly target existing chat files.
  • Bug Fix: Orphaned Session Files: Prevented the creation of duplicate, empty JSONL files during session resumption, which previously caused startup cleanup tasks to incorrectly delete valid conversation history.
  • Regression Testing: Added a new test case in packages/core/src/core/client.test.ts to verify that GeminiClient.initialize correctly forwards session data to startChat.
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.

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

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.

Code Review

This pull request updates the initialization flow of the Gemini CLI to accept and propagate resumedSessionData through the configuration and client initialization. This ensures that when resuming a session, the recording service reopens the existing session file instead of creating a new one, preventing potential data loss during startup retention cleanup. A unit test has been added to verify this behavior. I have no feedback to provide as there are no review comments.

Note: Security Review did not run due to the size of the PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/m A medium sized PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Resumig a session and exiting immediately without interacting deletes the session entirely

1 participant