You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Chat: typed message is lost on failed send; first message vanishes in a new chat #1391
Split out of #1388 (items 1 and 2), verified against main (3959eb0).
Problem
Two ways a typed chat message disappears without a trace:
Failed send loses the question. The composer clears its input as soon as Send is pressed, and on error the hooks remove the optimistic message, so only a toast remains. Repro: DevTools → Network → Offline, send a message in notebook or source chat.
First message in a brand-new notebook chat vanishes while waiting. Creating the session enables the getSession query; it returns messages: [] while the LLM call is still running, and the sync effect overwrites the list that holds the optimistic message.
Root cause
frontend/src/components/sources/ChatPanel.tsx:251-255 — handleSend calls onSendMessage(...) then setInput('') immediately (prop typed => void, line 38).
frontend/src/lib/hooks/use-notebook-chat.ts:230-235 and use-source-chat.ts:201-206 — on error: setMessages(prev => prev.filter(msg => !msg.id.startsWith('temp-'))).
use-notebook-chat.ts:59-63 — useEffect(() => { if (currentSession?.messages) setMessages(currentSession.messages) }) runs while a send is in flight. Same pattern in use-source-chat.ts:41-45.
Fix pointers
Make sendMessage resolve to success/failure and onSendMessage return a Promise; restore the text into the input on failure (or keep the optimistic message marked as failed with a retry action).
Skip the session→messages sync while isSending is true (or merge pending temp- messages into the fetched list).
Acceptance criteria
With the network offline or a 5xx from the API, the typed text is still available to the user after the error toast (notebook chat and source chat).
The first message of a new notebook chat stays visible until the reply arrives or fails.
Reproduced both on the latest main (a0f6f30) with hook tests, in notebook chat and source chat.
My plan: sendMessage in both hooks resolves to true or false, onSendMessage returns that promise, and the composer puts the text back in the input when the send fails. I'd rather restore the text than add a failed-message state with a retry action, since it needs no new UI or strings. For the first message, the session→messages effect skips while a send is in flight. I'd track that with a ref so the effect doesn't re-run when sending ends and briefly show the older session data.
Tests: a new use-notebook-chat.test.tsx, two cases in use-source-chat.test.tsx and one in ChatPanel.test.tsx. CHANGELOG entry too.
Activity
harshdazz commentedon Oct 6, 2026
Hi! I'd like to pick this one up.
Reproduced both on the latest
main(a0f6f30) with hook tests, in notebook chat and source chat.My plan:
sendMessagein both hooks resolves totrueorfalse,onSendMessagereturns that promise, and the composer puts the text back in the input when the send fails. I'd rather restore the text than add a failed-message state with a retry action, since it needs no new UI or strings. For the first message, the session→messages effect skips while a send is in flight. I'd track that with a ref so the effect doesn't re-run when sending ends and briefly show the older session data.Tests: a new
use-notebook-chat.test.tsx, two cases inuse-source-chat.test.tsxand one inChatPanel.test.tsx. CHANGELOG entry too.Let me know if you'd prefer the retry approach.