Skip to content

Resuming a session keeps plans/tracker/tasks bound to the startup session ID #24639

@Aaxhirrr

Description

@Aaxhirrr

What happened?

When a session is resumed, the conversation itself continues on the resumed session, but some session-scoped storage paths appear to stay bound to the fresh startup session ID that was created before resume was processed.

That means the resumed chat can end up with split state:

  • the conversation/history continues under the resumed session
  • but plan files, tracker state, and task artifacts can still be written under the startup-only session namespace

From a user perspective, this can make resumed work look inconsistent or partially "lost":

  • plan mode files may not be where the resumed session logically expects them
  • task tracker continuity can break across resume
  • session-scoped artifacts can be orphaned under a different session directory

This appears to affect current upstream main as of commit a93a1ebd on April 3, 2026.

What did you expect to happen?

After resuming a session, all session-scoped state should move with that resumed session consistently.

In other words, once Gemini CLI resumes session X, the CLI should use session X for:

  • chat recording
  • plan mode storage
  • tracker storage
  • task storage
  • any cleanup logic for session-scoped artifacts

There should not be a split where the resumed conversation uses one session ID while storage-backed workflow state continues using another.

Client information

Client Information
> /about
About Gemini CLI

CLI Version              0.36.0-nightly.20260317.2f90b4653
Git Commit               a93a1ebd6
Model                    Auto (Gemini 3)
Sandbox                  no sandbox
OS                       win32
Auth Method              Signed in with Google
Tier                     Gemini Code Assist in Google One AI Pro

Login information

  • Auth Method: Signed in with Google
  • Tier: Gemini Code Assist in Google One AI Pro

Anything else we need to know?

I searched for existing issues first and found related-but-different reports, but not a direct duplicate of this specific storage/session split:

  • #21311 covers resumed sessions becoming invalid / disappearing after auth failure
  • #21359 covers plan mode writes failing when sessionId is missing
  • #24532 covers sessions that appear to have never been recorded / cannot be resumed

This issue is different: resume itself can succeed, but resumed workflow state appears to stay partially bound to the startup session ID.

Technical analysis

The current implementation appears to construct Storage once using the startup session ID, then later mutate only the config session ID during resume:

  • packages/core/src/config/config.ts:1257
    • this.storage = new Storage(this.targetDir, this._sessionId);
  • packages/cli/src/gemini.tsx:592
    • config.setSessionId(resumedSessionData.conversation.sessionId);
  • packages/cli/src/ui/hooks/useSessionBrowser.ts:71
    • config.setSessionId(existingSessionId);
  • packages/core/src/config/config.ts:1733
    • setSessionId(sessionId: string): void { this._sessionId = sessionId; }

But Storage keeps its own captured readonly session ID:

  • packages/core/src/config/storage.ts:31
    • private readonly sessionId: string | undefined;
  • packages/core/src/config/storage.ts:36
    • constructor(targetDir: string, sessionId?: string) { ... this.sessionId = sessionId; }

And the session-scoped storage paths continue to derive from that captured Storage.sessionId:

  • packages/core/src/config/storage.ts:309
    • getProjectTempPlansDir()
  • packages/core/src/config/storage.ts:316
    • getProjectTempTrackerDir()
  • packages/core/src/config/storage.ts:343
    • getProjectTempTasksDir()

The tracker service is also cached off the storage-derived tracker path:

  • packages/core/src/config/config.ts:2753
    • getTrackerService()
  • packages/core/src/config/config.ts:2756
    • this.storage.getProjectTempTrackerDir()

And the prompt wiring exposes that tracker directory to the model:

  • packages/core/src/prompts/promptProvider.ts:76
    • context.config.storage.getProjectTempTrackerDir()

So the current behavior appears to be:

  1. CLI starts with fresh startup session ID A
  2. Storage is constructed using A
  3. user resumes existing session B
  4. config session ID changes to B
  5. storage-backed session paths can still resolve using A

This creates a split between the resumed conversation session and the storage-backed workflow session.

Why this matters

This is especially noticeable in workflows that rely on resume plus persistent state, for example:

  • resuming a session and continuing in plan mode
  • resuming a session and using the task tracker
  • resuming a session and expecting later cleanup to match the resumed session's artifacts

The bug is subtle because the resumed chat itself may look correct while plan/tracker/task state drifts into a different directory tree.

Suggested reproduction

I have not included a full end-to-end runtime repro here, but the logic looks straightforward to exercise:

  1. start a session and create plan/tracker/task state
  2. quit the CLI
  3. start Gemini CLI again so it gets a fresh startup session ID
  4. resume the previous session via --resume or the session browser
  5. continue using plan mode or tracker-backed workflow features
  6. inspect ~/.gemini/tmp/<project>/... and compare the resumed session ID versus the directories being used for plans/tracker/tasks

Expected fix direction

One of these should happen:

  • recreate or rebind Storage when setSessionId() is called during resume
  • make Storage read the current config session ID dynamically rather than capturing it only once
  • otherwise ensure all session-scoped services are refreshed after resume so they point at the resumed session namespace

Right now, Config.setSessionId() appears to update only config state, not the already-constructed storage/session-scoped services.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/coreIssues related to User Interface, OS Support, Core Functionalitypriority/p1Important and should be addressed in the near term.type/bug🔒 maintainer only⛔ Do not contribute. Internal roadmap item.

    Type

    No fields configured for Bug.

    Projects

    Status

    Closed

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions