diff --git a/ui/src/hooks/useTaskOperations.ts b/ui/src/hooks/useTaskOperations.ts index a7ee15a..04d4bde 100644 --- a/ui/src/hooks/useTaskOperations.ts +++ b/ui/src/hooks/useTaskOperations.ts @@ -28,14 +28,14 @@ export function useTaskOperations({ taskId, showToast, setUrlState, setShowCreat const handleComment = useCallback(async (body: string, attachments?: Array<{ name: string; contentBase64: string }>) => { if (!taskId) return; - try { - await postLocalTaskComment(taskId, body, 'user', attachments); - qc.invalidateQueries({ queryKey: ['localTaskDetail', taskId] }); - qc.invalidateQueries({ queryKey: ['localTasks'] }); - } catch { - showToast(t('toast.commentFailed'), 'error'); - } - }, [taskId, qc, showToast, t]); + // Let send failures propagate to ChatPane, which preserves the draft + + // attachments and shows an inline error with a retry button. Swallowing the + // error here would make ChatPane treat the send as successful and clear the + // user's input (losing the prompt and attachments on failure). + await postLocalTaskComment(taskId, body, 'user', attachments); + qc.invalidateQueries({ queryKey: ['localTaskDetail', taskId] }); + qc.invalidateQueries({ queryKey: ['localTasks'] }); + }, [taskId, qc]); const handleDelete = useCallback(async () => { if (!taskId) return;