Skip to content

Desktop: Sessions can get mixed up/overwritten during upgrade with multiple windows open #7601

@blackgirlbytes

Description

@blackgirlbytes

Description

A user reported losing an entire chat session when upgrading from 1.25.0 to 1.26.1 with 4-5 chat windows open. Two sessions got "mixed up" - one was completely overwritten/lost, and the other received the name that should have belonged to the lost session.

Steps to Reproduce

  1. Open Goose Desktop with multiple chat windows/tabs (4-5)
  2. Have at least two sessions that are still showing as "New Chat" (unnamed, no messages yet or just started)
  3. Upgrade Goose (e.g., 1.25.0 → 1.26.1)
  4. After restart, observe that sessions may be mixed up - one session's content may be lost and another may have the wrong name

Expected Behavior

All sessions should be preserved with their correct content and names after an upgrade, regardless of how many windows are open.

Actual Behavior

  • One session was completely lost/overwritten
  • Another session received the name that belonged to the lost session

Root Cause Analysis

Investigation identified several contributing factors in the 1.25.0 → 1.26.1 changes:

1. In-memory session cache doesn't survive restarts

The resultsCache in useChatStream.ts caches {messages, session} by sessionId but is not persisted:

const resultsCache = new Map<string, { messages: Message[]; session: Session }>();

When the app restarts during upgrade, this cache is cleared and sessions are reloaded from SQLite, but window-to-session associations may be lost.

2. "New Chat" session reuse logic

In useNavigationSessions.ts, the handleNewChat function reuses existing empty sessions:

const emptyNewSession = sessionsRef.current.find((s) => shouldShowNewChatTitle(s));
if (emptyNewSession) {
  resumeSession(emptyNewSession, setView);
}

With multiple unnamed sessions across windows, this could route to the wrong session after a restart.

3. Async session naming race condition

Session names are generated asynchronously via maybe_update_name() which spawns a background task. If the app restarts during this process, names could be written to incorrect sessions.

4. Client/server sync changes (PR #7438)

The "client is not the source of truth" change removed conversation_so_far from client requests, changing how session state synchronizes. This was intended to fix bugs but may have edge cases during restarts.

Related Issues

Suggested Fixes

  1. Persist window-to-session mapping - Store the activeSessions array to survive restarts, or use Electron's session restoration APIs

  2. Add session integrity verification - When loading a session into a window, verify the content matches expectations (e.g., check message count, first message content)

  3. Scope "New Chat" reuse per-window - The empty session reuse logic should be window-scoped, not global

  4. Add upgrade safeguards - Consider gracefully closing/saving all sessions before an upgrade, or blocking upgrades when multiple windows have unsaved state

  5. Add session content hashing - Store a hash of session content that can be verified after restart to detect corruption/mixing

  6. Automatic backup before upgrade - Automatically export all open sessions to disk (e.g., as JSON/markdown files) before killing the app for an upgrade. This provides a recovery path even if something goes wrong during the upgrade process.

Impact

High - Users can lose substantial work with no way to recover it. This is especially problematic for users who keep multiple long-running sessions open.

Environment

  • OS: macOS
  • Versions affected: Upgrade from 1.25.0 to 1.26.1 (likely affects other upgrade paths too)
  • Interface: Desktop (Electron)

User Quote

"The work on this app is amazing but please show care not to lose data with these super fast paced changes and upgrades...this has cost me a lot of time and could have been much worse had it been another chat."

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions