Skip to content

fix(desktop): prevent stale session recovery across profile switches - #66889

Closed
akivavh wants to merge 1 commit into
NousResearch:mainfrom
akivavh:agent/fix-profile-switch-session-race
Closed

fix(desktop): prevent stale session recovery across profile switches#66889
akivavh wants to merge 1 commit into
NousResearch:mainfrom
akivavh:agent/fix-profile-switch-session-race

Conversation

@akivavh

@akivavh akivavh commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes a Desktop race that could show Prompt failed: session not found when switching profiles.

  • Clears the foreground session identity synchronously before activating the next profile gateway.
  • Cancels an in-flight prompt if its profile/session context changes.
  • Prevents recovery from resuming the previous profile's stored session through the newly active gateway.
  • Adds regression coverage for both timing paths.

Root cause

The fresh-session request was handled through a passive React effect. Profile activation could therefore complete before the old foreground session references were cleared.

If an earlier prompt.submit subsequently returned 4007 session not found, the recovery path could attempt session.resume with the previous profile's durable session ID against the new profile gateway.

Behavior after this change

Profile switching tears down the old foreground identity before gateway activation continues. Any prompt or recovery already in flight for the abandoned context is silently cancelled instead of producing an error or crossing profile boundaries.

This does not modify or delete chats, profiles, or configuration data.

Scope

Desktop-only change across five files:

  • apps/desktop/src/app/contrib/wiring.tsx
  • apps/desktop/src/app/hooks/use-fresh-session-requests.ts
  • apps/desktop/src/app/hooks/use-fresh-session-requests.test.tsx
  • apps/desktop/src/app/session/hooks/use-prompt-actions/submit.ts
  • apps/desktop/src/app/session/hooks/use-prompt-actions/index.test.tsx

Validation

  • 106 focused profile/session tests passed.
  • Desktop typecheck passed.
  • Production build passed.
  • Full parallel UI suite passed 1,343 / 1,347; the four unrelated timeout/cleanup flakes passed when their two files were rerun in isolation (5 / 5).

@akivavh
akivavh marked this pull request as ready for review July 18, 2026 11:14
@alt-glitch alt-glitch added type/bug Something isn't working comp/desktop Electron desktop app (apps/desktop/*) P2 Medium — degraded but workaround exists sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages labels Jul 18, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Related to the Desktop session-routing repairs in #62413 and #65283, but this change fixes the distinct profile-switch timing window before prompt.submit recovery.

@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the focused Desktop race fix. The premise is verified against current main: selectProfile() requests a fresh session before initiating gateway activation (apps/desktop/src/store/profile.ts:336-348), while the foreground reset remains a later React effect (apps/desktop/src/app/contrib/wiring.tsx:411-421). A failed prompt.submit then enters recovery and calls session.resume before the existing post-resume drift check (apps/desktop/src/app/session/hooks/use-prompt-actions/submit.ts:462-476).

The patch makes the fresh-session reset synchronous at the atom mutation boundary and prevents recovery when the submit context has drifted. The added tests cover both the reset ordering and the in-flight 4007 path. No blocking issue identified from the diff.

Automated hermes-sweeper review.

@teknium1 teknium1 added sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform area/sessions Session lifecycle, resume, persistence, history area/profiles Multi-profile isolation, HERMES_HOME scoping labels Jul 19, 2026
@OutThisLife

Copy link
Copy Markdown
Collaborator

Superseded by #81261.

Thanks for this — the no-cross-profile-resume constraint is carried over there, with you credited via Co-authored-by.

Consolidating because this is one bug class across several PRs: main had three hand-rolled copies of the same stale-session recovery (prompt.submit, session.interrupt, session.redirect), and the RPCs that never got a copy — attach, /compress, checkpoint restore, tile actions — each failed the same way. #81261 makes it one resolver and routes every path through it, so the next session-scoped RPC we add inherits the fix instead of needing a fourth copy.

@OutThisLife OutThisLife closed this Aug 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/profiles Multi-profile isolation, HERMES_HOME scoping area/sessions Session lifecycle, resume, persistence, history comp/desktop Electron desktop app (apps/desktop/*) P2 Medium — degraded but workaround exists sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants