Skip to content

[Bug] Opening another chat while a reply streams builds this chat's memory prompt from the other chat's memory #6935

Open

Description

@Karanvir1729

📦 Deployment Method

Other (run from source: yarn install, next dev)

📌 Version

v2.16.1 (main at 1d3dc33)

💻 Operating System

macOS

📌 System Version

macOS 26.2

🌐 Browser

Other

📌 Browser Version

Chromium 153.0.8010.12 (Playwright, headless)

🐛 Bug Description

When a reply in chat A finishes while chat B is open, NextChat builds chat A's new memory prompt (the long-term summary shown as "Memory Prompt" in the chat's settings) from chat B's memory instead of chat A's own. Chat A's earlier summary is dropped, and from then on chat A sends the model a summary that was built from the other chat.

It needs a chat that is long enough to be summarized: with the defaults ("Send Memory" on, "History Compression Threshold" 1000), that is once more than 1000 tokens have accumulated since the last summary. One way to hit it is to send a message in such a chat and open another chat while the answer streams. If the chat you open has no memory prompt (a new chat, for example), chat A's earlier summary is simply lost.

📷 Recurrence Steps

  1. Default settings, OpenAI provider.
  2. In chat A, have an exchange long enough to be summarized. Chat A's settings show its "Memory Prompt".
  3. Start chat B and do the same, so chat B has its own memory prompt.
  4. Go back to chat A and ask something with a long answer. While the answer is still streaming, click chat B in the sidebar.
  5. Wait for the answer to finish and go back to chat A. Its memory prompt (shown in the chat's settings) is now a summary of chat B's memory plus chat A's last exchange, and chat A's first exchange is gone from it. The next question in chat A sends this summary to the model.

🚦 Expected Behavior

A chat's summary is built from that chat's own earlier memory, whichever chat is open when its reply finishes.

📝 Additional Information

How it was checked: Playwright against a local NextChat (next dev at 1d3dc33), with BASE_URL pointing at a local stub of the OpenAI API that logs every request. Each chat message carries a tag ([chat-A], [chat-B]), and each stub summary names the tags and earlier summaries it was given, so the stub's log shows which memory each summary request carried. The steps were as above: chat A and chat B have one long exchange each, then a second question in chat A whose answer streams for about 4 s.

  • Clicking chat B 700 ms after chat A's answer started streaming: in 10 of 10 runs, chat A's summary request carried chat B's memory and not chat A's own. Chat A's memory prompt became that summary (built from chat B's memory plus chat A's last exchange), and chat A's next question sent it to the model.
  • Control, the same steps but clicking chat B only after chat A's answer and its summary were done: 0 of 10.

Root cause: summarizeSession(refreshTitle, targetSession) summarizes targetSession, but it gets the memory prompt from get().getMemoryPrompt() (app/store/chat.ts:745). That function reads get().currentSession() (app/store/chat.ts:531), which is the chat on screen. summarizeSession runs from onFinish → onNewMessage(botMessage, session) (app/store/chat.ts:478, 404) when the reply ends, so the chat on screen is whichever one the user has opened by then. getMessagesWithMemory makes the same call after await isMcpEnabled() (app/store/chat.ts:591), so a chat switch during that await could do the same; that path was not measured.

AI assistance: Claude (Claude Code) investigated this, reproduced it with the measurements above, wrote a fix and a test, and drafted this report. I have not reproduced it by hand or reviewed the fix myself yet.

Activity

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

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