Skip to content

fix(core): reset session-scoped state on resumption#26342

Merged
cocosheng-g merged 5 commits intomainfrom
fix/issue-24639-session-state-split
May 1, 2026
Merged

fix(core): reset session-scoped state on resumption#26342
cocosheng-g merged 5 commits intomainfrom
fix/issue-24639-session-state-split

Conversation

@cocosheng-g
Copy link
Copy Markdown
Contributor

@cocosheng-g cocosheng-g commented May 1, 2026

Summary

Fixes the "session state split" issue where resuming a previous session kept several internal services and states bound to the initial "startup" session ID instead of transitioning to the resumed session's identity.

Details

The Problem

When the Gemini CLI starts, it immediately generates a fresh "startup" session ID (Session A). If the user then resumes a previous session (Session B) via the Session Browser or --resume flag, the conversation moves to Session B, but internal services like the Task Tracker and Plan Mode often remained bound to Session A's temporary directory. This led to:

  • New tasks being written to the wrong session folder.
  • Approved plans being "lost" or split across session namespaces.
  • Stale UI state (like topic titles) leaking from the startup session into the resumed one.

The Fix

This PR updates Config.setSessionId() to perform a comprehensive reset of all session-scoped state:

  • Service Invalidation: Sets trackerService to undefined, forcing it to be re-initialized with the correct resumed path on its next use.
  • State Clearing: Explicitly clears approvedPlanPath, topicState (title/intent), and skillManager (active skills) to ensure Session B starts with a clean slate.
  • Artifact Continuity: Because the TrackerService is file-backed, once it is re-initialized with the resumed path, it automatically restores visibility of all tasks previously saved in Session B.
  • Thorough Session Reset: Based on PR feedback, added resets for:
    • modelAvailabilityService: Clears stale fallback/terminal states.
    • modelQuotas, lastRetrievedQuota, lastQuotaFetchTime: Ensures fresh quota information is fetched for the resumed session.
    • Forced Quota Event: Explicitly emits a QuotaChanged event with undefined values to ensure the React UI clears its display immediately upon resumption.
    • hasAccessToPreviewModel: Re-evaluates access to preview models.
  • Transient State Reset: Clears telemetry counters, model switch timers, etc.

Related Issues

Fixes #24639

How to Validate

  1. Run a session and create a task or approve a plan.
  2. Quit and restart the CLI.
  3. Resume the previous session via the Session Browser.
  4. Verify Path Continuity: Check that new tasks created in the resumed session are saved in the same directory as the previous tasks (under ~/.gemini/tmp/<project>/<session-id>/tracker).
  5. Verify State Isolation: Ensure the UI topic title and any temporary plan approvals from the startup session are cleared upon resumption.

Pre-Merge Checklist

  • Added/updated tests:
    • Added comprehensive reset test to packages/core/src/config/config.test.ts verifying all 15+ reset variables.
    • Added reset test to packages/core/src/skills/skillManager.test.ts.
  • Validated on required platforms/methods (MacOS)

@cocosheng-g cocosheng-g requested a review from a team as a code owner May 1, 2026 17:13
@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 an issue where internal session state persisted incorrectly when resuming or switching between sessions. By centralizing the reset logic within the configuration service and providing explicit reset capabilities to core state managers, the system now ensures a clean slate for each session, preventing data leakage and ensuring correct file path scoping.

Highlights

  • Session State Reset: Implemented a comprehensive reset mechanism in Config.setSessionId() to ensure all session-scoped variables, including approved plans, topic states, and skill managers, are cleared when switching sessions.
  • Component Reset Methods: Added dedicated reset() methods to TopicState and SkillManager to allow for granular clearing of internal session-specific data.
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 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 counter productive. 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.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 1, 2026

Size Change: +710 B (0%)

Total Size: 33.9 MB

Filename Size Change
./bundle/chunk-4IA56M2J.js 0 B -49.2 kB (removed) 🏆
./bundle/chunk-AM7KY4MR.js 0 B -12.5 kB (removed) 🏆
./bundle/chunk-IP44KZI3.js 0 B -3.8 kB (removed) 🏆
./bundle/chunk-JSFVUZ42.js 0 B -14.7 MB (removed) 🏆
./bundle/chunk-T45DLOOB.js 0 B -3.43 kB (removed) 🏆
./bundle/chunk-WYMPQT66.js 0 B -19.5 kB (removed) 🏆
./bundle/chunk-Z2SJB2OS.js 0 B -2.72 MB (removed) 🏆
./bundle/chunk-ZW36NTOO.js 0 B -657 kB (removed) 🏆
./bundle/core-AA3CQ4CM.js 0 B -48.2 kB (removed) 🏆
./bundle/devtoolsService-THCPN2KO.js 0 B -28 kB (removed) 🏆
./bundle/gemini-MEGSFPG5.js 0 B -581 kB (removed) 🏆
./bundle/interactiveCli-MNIALKWO.js 0 B -1.32 MB (removed) 🏆
./bundle/liteRtServerManager-KFGCSXCQ.js 0 B -2.11 kB (removed) 🏆
./bundle/oauth2-provider-V6CGEQV6.js 0 B -9.16 kB (removed) 🏆
./bundle/chunk-366XNJXS.js 3.43 kB +3.43 kB (new file) 🆕
./bundle/chunk-5EJAZVKB.js 14.7 MB +14.7 MB (new file) 🆕
./bundle/chunk-AVHLJDXR.js 12.5 kB +12.5 kB (new file) 🆕
./bundle/chunk-GADO5GZI.js 19.5 kB +19.5 kB (new file) 🆕
./bundle/chunk-IM2243MQ.js 3.8 kB +3.8 kB (new file) 🆕
./bundle/chunk-LCNVLC3Z.js 49.2 kB +49.2 kB (new file) 🆕
./bundle/chunk-LCOIY63E.js 657 kB +657 kB (new file) 🆕
./bundle/chunk-OCSMUXVC.js 2.72 MB +2.72 MB (new file) 🆕
./bundle/core-7SYE7KKK.js 48.2 kB +48.2 kB (new file) 🆕
./bundle/devtoolsService-6UPUGM2E.js 28 kB +28 kB (new file) 🆕
./bundle/gemini-5TIHJ2BN.js 581 kB +581 kB (new file) 🆕
./bundle/interactiveCli-ODCANXU3.js 1.32 MB +1.32 MB (new file) 🆕
./bundle/liteRtServerManager-U5V6QDQF.js 2.11 kB +2.11 kB (new file) 🆕
./bundle/oauth2-provider-3RKZIL2W.js 9.16 kB +9.16 kB (new file) 🆕
ℹ️ View Unchanged
Filename Size Change
./bundle/bundled/third_party/index.js 8 MB 0 B
./bundle/chunk-34MYV7JD.js 2.45 kB 0 B
./bundle/chunk-5AUYMPVF.js 858 B 0 B
./bundle/chunk-5PS3AYFU.js 1.18 kB 0 B
./bundle/chunk-664ZODQF.js 124 kB 0 B
./bundle/chunk-DAHVX5MI.js 206 kB 0 B
./bundle/chunk-IBHWQ36L.js 1.97 MB 0 B
./bundle/chunk-IUUIT4SU.js 56.5 kB 0 B
./bundle/chunk-RJTRUG2J.js 39.8 kB 0 B
./bundle/cleanup-KERBGOI3.js 0 B -932 B (removed) 🏆
./bundle/devtools-36NN55EP.js 696 kB 0 B
./bundle/dist-T73EYRDX.js 356 B 0 B
./bundle/events-XB7DADIJ.js 418 B 0 B
./bundle/examples/hooks/scripts/on-start.js 188 B 0 B
./bundle/examples/mcp-server/example.js 1.43 kB 0 B
./bundle/gemini.js 5.1 kB 0 B
./bundle/getMachineId-bsd-TXG52NKR.js 1.55 kB 0 B
./bundle/getMachineId-darwin-7OE4DDZ6.js 1.55 kB 0 B
./bundle/getMachineId-linux-SHIFKOOX.js 1.34 kB 0 B
./bundle/getMachineId-unsupported-5U5DOEYY.js 1.06 kB 0 B
./bundle/getMachineId-win-6KLLGOI4.js 1.72 kB 0 B
./bundle/memoryDiscovery-KH2QDS2N.js 980 B 0 B
./bundle/multipart-parser-KPBZEGQU.js 11.7 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/client/main.js 222 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/_client-assets.js 229 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/index.js 13.4 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/types.js 132 B 0 B
./bundle/sandbox-macos-permissive-open.sb 890 B 0 B
./bundle/sandbox-macos-permissive-proxied.sb 1.31 kB 0 B
./bundle/sandbox-macos-restrictive-open.sb 3.36 kB 0 B
./bundle/sandbox-macos-restrictive-proxied.sb 3.56 kB 0 B
./bundle/sandbox-macos-strict-open.sb 4.82 kB 0 B
./bundle/sandbox-macos-strict-proxied.sb 5.02 kB 0 B
./bundle/src-QVCVGIUX.js 47 kB 0 B
./bundle/start-3WN5OKCD.js 0 B -652 B (removed) 🏆
./bundle/tree-sitter-7U6MW5PS.js 274 kB 0 B
./bundle/tree-sitter-bash-34ZGLXVX.js 1.84 MB 0 B
./bundle/cleanup-3S4ZLEXJ.js 932 B +932 B (new file) 🆕
./bundle/start-5EWBAABF.js 652 B +652 B (new file) 🆕

compressed-size-action

Copy link
Copy Markdown
Contributor

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

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 centralizes and expands the session state reset logic within the Config class, specifically updating setSessionId to clear various session-scoped variables and removing redundant resets in resetNewSessionState. Additionally, a reset method was added to SkillManager to clear active skill names. Feedback suggests that the reset logic in Config should be more comprehensive by including additional internal state variables, such as model quotas and availability services, to ensure a completely fresh state for new sessions.

Comment thread packages/core/src/config/config.ts
@cocosheng-g
Copy link
Copy Markdown
Contributor Author

/gemini review

Copy link
Copy Markdown
Contributor

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

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 improves session state management by ensuring that a comprehensive set of session-scoped properties are reset within the Config class when a new session is initialized. These properties include topic state, skill manager status, API request tracking, and various quota-related metrics. Additionally, a reset method was added to the SkillManager to clear active skill names. I have no feedback to provide as there were no review comments to evaluate.

@gemini-cli gemini-cli Bot added priority/p1 Important and should be addressed in the near term. area/core Issues related to User Interface, OS Support, Core Functionality 🔒 maintainer only ⛔ Do not contribute. Internal roadmap item. labels May 1, 2026
@devr0306
Copy link
Copy Markdown
Contributor

devr0306 commented May 1, 2026

Code Review

Thank you for the PR! This thoroughly addresses the session state split issue and handles the necessary cleanup on resumption.

I have reviewed the changes and found two minor points related to the React frontend state that need to be addressed:

  1. Stale Quota Display on the Frontend (Bug):
    In Config.setSessionId(), the PR clears the internal quota state (modelQuotas.clear(), lastEmittedQuotaRemaining = undefined, etc.), but it does not emit an event to the UI that the quota has changed. Because this.emitQuotaChangedEvent() is not called here, the React frontend will not be notified of the reset and will continue displaying the quota stats from the previous session until the next active quota fetch.
    Recommendation: Call this.emitQuotaChangedEvent() at the end of the quota reset block in setSessionId(). (For comparison, Config.setModel() currently does this correctly).

  2. Topic State Reactivity:
    The PR adds this.topicState.reset(). TopicState itself is not an event emitter, so it relies on the frontend re-fetching the topic on subsequent renders. While this is likely fine since the React component tree might fully re-render upon session resumption, it is worth manually verifying that the UI topic title actually disappears immediately as intended without needing an explicit event.

Once the quota event emission is added, this should be good to go. The removal of this.approvedPlanPath = undefined; from resetNewSessionState was also a good catch to remove duplication.

@cocosheng-g
Copy link
Copy Markdown
Contributor Author

addressed!

Copy link
Copy Markdown
Contributor

@devr0306 devr0306 left a comment

Choose a reason for hiding this comment

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

LGTM

@cocosheng-g cocosheng-g enabled auto-merge May 1, 2026 18:37
@cocosheng-g cocosheng-g added this pull request to the merge queue May 1, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks May 1, 2026
@cocosheng-g cocosheng-g added this pull request to the merge queue May 1, 2026
Merged via the queue into main with commit 408afd3 May 1, 2026
28 checks passed
@cocosheng-g cocosheng-g deleted the fix/issue-24639-session-state-split branch May 1, 2026 21:34
TirthNaik-99 pushed a commit to TirthNaik-99/gemini-cli that referenced this pull request May 4, 2026
kimjune01 pushed a commit to kimjune01/gemini-cli-claude that referenced this pull request May 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/core Issues related to User Interface, OS Support, Core Functionality 🔒 maintainer only ⛔ Do not contribute. Internal roadmap item. priority/p1 Important and should be addressed in the near term.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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

2 participants