diff --git a/plugins/attachment-resources/src/components/AttachmentRefInput.svelte b/plugins/attachment-resources/src/components/AttachmentRefInput.svelte
index a9fc603dd4..e67f18ca96 100644
--- a/plugins/attachment-resources/src/components/AttachmentRefInput.svelte
+++ b/plugins/attachment-resources/src/components/AttachmentRefInput.svelte
@@ -210,8 +210,12 @@
 
   async function onMessage (event: CustomEvent) {
     loading = true
-    await createAttachments()
-    dispatch('message', { message: event.detail, attachments: attachments.size })
+    try {
+      await createAttachments()
+      dispatch('message', { message: event.detail, attachments: attachments.size })
+    } finally {
+      loading = false
+    }
   }
 
   async function onUpdate (event: CustomEvent) {
diff --git a/plugins/chunter-resources/src/components/ChannelView.svelte b/plugins/chunter-resources/src/components/ChannelView.svelte
index 5d5566e335..57d472604e 100644
--- a/plugins/chunter-resources/src/components/ChannelView.svelte
+++ b/plugins/chunter-resources/src/components/ChannelView.svelte
@@ -75,6 +75,7 @@
 
     _id = generateId()
     isScrollForced = true
+    loading = false
   }
 
   function openThread (_id: Ref<Message>) {
@@ -106,6 +107,7 @@
   savedAttachmentsQuery.query(attachment.class.SavedAttachments, {}, (res) => {
     savedAttachmentsIds = res.map((r) => r.attachedTo)
   })
+  let loading = false
 </script>
 
 <PinnedMessages {space} {pinnedIds} />
@@ -120,7 +122,7 @@
   {savedAttachmentsIds}
 />
 <div class="reference">
-  <AttachmentRefInput {space} {_class} objectId={_id} on:message={onMessage} />
+  <AttachmentRefInput bind:loading {space} {_class} objectId={_id} on:message={onMessage} />
 </div>
 
 <style lang="scss">
diff --git a/plugins/chunter-resources/src/components/CommentInput.svelte b/plugins/chunter-resources/src/components/CommentInput.svelte
index 4f852933c6..f604c93761 100644
--- a/plugins/chunter-resources/src/components/CommentInput.svelte
+++ b/plugins/chunter-resources/src/components/CommentInput.svelte
@@ -147,5 +147,5 @@
   {shouldSaveDraft}
   on:message={onMessage}
   on:update={onUpdate}
-  {loading}
+  bind:loading
 />
diff --git a/plugins/chunter-resources/src/components/Message.svelte b/plugins/chunter-resources/src/components/Message.svelte
index f3c41e704e..1d38295b9a 100644
--- a/plugins/chunter-resources/src/components/Message.svelte
+++ b/plugins/chunter-resources/src/components/Message.svelte
@@ -165,6 +165,7 @@
       attachments: newAttachments
     })
     isEditing = false
+    loading = false
   }
 
   function getEmployee (message: WithLookup<ChunterMessage>): Employee | undefined {
@@ -245,6 +246,7 @@
     })
     return res
   }
+  let loading = false
 </script>
 
 <div class="container" class:highlighted={isHighlighted} id={message._id}>
@@ -270,6 +272,7 @@
         content={message.content}
         showSend={false}
         on:message={onMessageEdit}
+        bind:loading
       />
       <div class="flex-row-reverse gap-2 reverse">
         <Button label={chunter.string.EditCancel} on:click={() => (isEditing = false)} />
diff --git a/plugins/chunter-resources/src/components/Thread.svelte b/plugins/chunter-resources/src/components/Thread.svelte
index d33837e405..543d2845de 100644
--- a/plugins/chunter-resources/src/components/Thread.svelte
+++ b/plugins/chunter-resources/src/components/Thread.svelte
@@ -157,12 +157,14 @@
     await createBacklinks(client, parent.space, chunter.class.ChunterSpace, commentId, message)
 
     commentId = generateId()
+    loading = false
   }
   let comments: ThreadMessage[] = []
 
   async function getChannel (_id: Ref<ChunterSpace>): Promise<ChunterSpace | undefined> {
     return await client.findOne(chunter.class.ChunterSpace, { _id })
   }
+  let loading = false
 </script>
 
 <div class="ml-8 mt-4">
@@ -202,6 +204,7 @@
         _class={chunter.class.ThreadMessage}
         objectId={commentId}
         on:message={onMessage}
+        bind:loading
       />
     </div>
   {/if}
diff --git a/plugins/chunter-resources/src/components/ThreadView.svelte b/plugins/chunter-resources/src/components/ThreadView.svelte
index b4af305cd3..64931785c2 100644
--- a/plugins/chunter-resources/src/components/ThreadView.svelte
+++ b/plugins/chunter-resources/src/components/ThreadView.svelte
@@ -172,6 +172,7 @@
 
     commentId = generateId()
     isScrollForced = true
+    loading = false
   }
   let comments: ThreadMessage[] = []
 
@@ -193,6 +194,7 @@
     }
   }
   let newMessagesPos: number = -1
+  let loading = false
 </script>
 
 <div class="header">
@@ -234,6 +236,7 @@
     _class={chunter.class.ThreadMessage}
     objectId={commentId}
     on:message={onMessage}
+    bind:loading
   />
 </div>
 
diff --git a/plugins/chunter-resources/src/components/activity/TxCommentCreate.svelte b/plugins/chunter-resources/src/components/activity/TxCommentCreate.svelte
index a54eaa151a..d39cfbc50d 100644
--- a/plugins/chunter-resources/src/components/activity/TxCommentCreate.svelte
+++ b/plugins/chunter-resources/src/components/activity/TxCommentCreate.svelte
@@ -62,7 +62,7 @@
 <div class:editing class="content-accent-color">
   {#if edit}
     <AttachmentRefInput
-      {loading}
+      bind:loading
       bind:this={refInput}
       _class={value._class}
       objectId={value._id}
diff --git a/plugins/request-resources/src/components/RequestActions.svelte b/plugins/request-resources/src/components/RequestActions.svelte
index 87c8406801..3deb714d45 100644
--- a/plugins/request-resources/src/components/RequestActions.svelte
+++ b/plugins/request-resources/src/components/RequestActions.svelte
@@ -71,6 +71,7 @@
     // We need to update backlinks before and after.
     await updateBacklinks(client, value.attachedTo, value.attachedToClass, value._id, message)
     refInput.submit()
+    loading = false
   }
 
   function commentIsEmpty (message: string, attachments: number | undefined): boolean {
@@ -97,6 +98,7 @@
       disabled
     }
   ]
+  let loading = false
 </script>
 
 {#if value.status === RequestStatus.Active}
@@ -111,6 +113,7 @@
       on:update={onUpdate}
       placeholder={request.string.PleaseTypeMessage}
       extraActions={approvable ? extraActions : undefined}
+      bind:loading
     />
   </div>
 {/if}
diff --git a/plugins/telegram-resources/src/components/Chat.svelte b/plugins/telegram-resources/src/components/Chat.svelte
index 35c0ea58d4..e10c3914ba 100644
--- a/plugins/telegram-resources/src/components/Chat.svelte
+++ b/plugins/telegram-resources/src/components/Chat.svelte
@@ -128,6 +128,7 @@
     )
 
     objectId = generateId()
+    loading = false
   }
 
   function getName (message: TelegramMessage, accounts: EmployeeAccount[]): string {
@@ -185,6 +186,7 @@
       })
     }
   }
+  let loading = false
 </script>
 
 {#if object !== undefined}
@@ -270,6 +272,7 @@
           _class={telegram.class.NewMessage}
           {objectId}
           on:message={onMessage}
+          bind:loading
         />
       {/if}
     </div>