From abac8268ec4dce949df7c7702e014746f3292700 Mon Sep 17 00:00:00 2001 From: Tanmay Deep Sharma Date: Fri, 15 May 2026 17:16:44 +0530 Subject: [PATCH] fix(reply-box): block empty sends during async audio attachment upload --- .../components/widgets/conversation/ReplyBox.vue | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/app/javascript/dashboard/components/widgets/conversation/ReplyBox.vue b/app/javascript/dashboard/components/widgets/conversation/ReplyBox.vue index 872f68640..aa8b9571e 100644 --- a/app/javascript/dashboard/components/widgets/conversation/ReplyBox.vue +++ b/app/javascript/dashboard/components/widgets/conversation/ReplyBox.vue @@ -217,7 +217,11 @@ export default { isReplyButtonDisabled() { if (this.isEditorDisabled) return true; if (this.isATwitterInbox) return true; - if (this.hasAttachments || this.hasRecordedAudio) return false; + // Note: only `hasAttachments` (attachedFiles populated) enables send. + // `hasRecordedAudio` becomes true the moment recording stops, but the + // file upload that follows is async — sending in that window produced + // empty messages that Meta rejected with "text.body is required". + if (this.hasAttachments) return false; return ( this.isMessageEmpty || @@ -764,6 +768,13 @@ export default { if (this.isReplyButtonDisabled) { return; } + // Defensive: never send a payload that has neither content nor a file. + // The send button's disabled state already covers this, but guard here + // too so any other entry point (hotkey, programmatic) cannot create the + // empty Message rows that Meta rejects with "text.body is required". + if (this.isMessageEmpty && !this.hasAttachments) { + return; + } if (!this.showMentions) { const copilotAcceptedMessage = this.getCopilotAcceptedMessage(); const isOnWhatsApp =