@@ -95,6 +95,9 @@ export function useConversationSync(conversationId: string | undefined) {
9595 // triggers the save effect, but nothing actually changed — saving would bump updatedAt
9696 // and cause the conversation to jump to the top of the sidebar)
9797 const skipNextSaveRef = useRef ( false ) ;
98+ // Ref for currentConversationId so the save effect doesn't re-trigger on conversation
99+ // switch (which would consume the skipNextSaveRef before the real message-load render)
100+ const currentConversationIdRef = useRef ( currentConversation ?. id ) ;
98101
99102 // Load conversation when it changes
100103 useEffect ( ( ) => {
@@ -127,11 +130,15 @@ export function useConversationSync(conversationId: string | undefined) {
127130 }
128131 } , [ currentConversation ?. id ] ) ; // eslint-disable-line react-hooks/exhaustive-deps
129132
130- // Save conversation when messages change (debounced)
131- const currentConversationId = currentConversation ?. id ;
133+ // Save conversation when messages change (debounced).
134+ // currentConversationId is accessed via ref so that switching conversations doesn't
135+ // trigger this effect — otherwise it fires before the message-load render and
136+ // consumes skipNextSaveRef too early, causing a spurious save that bumps updatedAt.
137+ currentConversationIdRef . current = currentConversation ?. id ;
132138 useEffect ( ( ) => {
133- if ( isStreaming || ! currentConversationId || messages . length === 0 ) return ;
134- if ( loadedConversationIdRef . current !== currentConversationId ) return ;
139+ const convId = currentConversationIdRef . current ;
140+ if ( isStreaming || ! convId || messages . length === 0 ) return ;
141+ if ( loadedConversationIdRef . current !== convId ) return ;
135142
136143 // After loading a conversation, the messages store changes which triggers this effect.
137144 // Skip that first save to avoid bumping updatedAt (which reorders the sidebar).
@@ -145,15 +152,15 @@ export function useConversationSync(conversationId: string | undefined) {
145152 }
146153
147154 saveTimeoutRef . current = setTimeout ( ( ) => {
148- updateConversation ( currentConversationId , messages , selectedModels ) ;
155+ updateConversation ( currentConversationIdRef . current ! , messages , selectedModels ) ;
149156 } , 100 ) ;
150157
151158 return ( ) => {
152159 if ( saveTimeoutRef . current ) {
153160 clearTimeout ( saveTimeoutRef . current ) ;
154161 }
155162 } ;
156- } , [ messages , isStreaming , currentConversationId , selectedModels , updateConversation ] ) ;
163+ } , [ messages , isStreaming , selectedModels , updateConversation ] ) ;
157164
158165 /**
159166 * Fork a conversation, optionally up to a specific message.
0 commit comments