@@ -213,19 +213,26 @@ ipcMain.handle(
213213 thinkingLevel,
214214 } ) ;
215215 try {
216- // Early exit: empty message during streaming = interrupt
217- // This allows Esc key to interrupt without creating empty user messages
218- if ( ! message . trim ( ) && aiService . isStreaming ( workspaceId ) ) {
219- log . debug ( "sendMessage handler: Empty message during streaming, interrupting" ) ;
220- const stopResult = await aiService . stopStream ( workspaceId ) ;
221- if ( ! stopResult . success ) {
222- log . error ( "Failed to stop stream:" , stopResult . error ) ;
223- return {
224- success : false ,
225- error : createUnknownSendMessageError ( stopResult . error ) ,
226- } ;
216+ // Early exit: empty message = either interrupt (if streaming) or invalid input
217+ // This prevents race conditions where empty messages arrive after streaming stops
218+ if ( ! message . trim ( ) ) {
219+ // If streaming, this is an interrupt request (from Esc key)
220+ if ( aiService . isStreaming ( workspaceId ) ) {
221+ log . debug ( "sendMessage handler: Empty message during streaming, interrupting" ) ;
222+ const stopResult = await aiService . stopStream ( workspaceId ) ;
223+ if ( ! stopResult . success ) {
224+ log . error ( "Failed to stop stream:" , stopResult . error ) ;
225+ return {
226+ success : false ,
227+ error : createUnknownSendMessageError ( stopResult . error ) ,
228+ } ;
229+ }
230+ return { success : true } ;
227231 }
228- return { success : true } ;
232+
233+ // If not streaming, reject empty message to prevent creating empty user messages
234+ log . debug ( "sendMessage handler: Rejected empty message (not streaming)" ) ;
235+ return { success : true } ; // Return success to avoid error notification in UI
229236 }
230237
231238 // If editing, truncate history after the message being edited
0 commit comments