diff --git a/keyserver/src/creators/thread-creator.js b/keyserver/src/creators/thread-creator.js
--- a/keyserver/src/creators/thread-creator.js
+++ b/keyserver/src/creators/thread-creator.js
@@ -192,6 +192,10 @@
     validateMembers: { initialMemberIDs, ghostMemberIDs },
   } = await promiseAll(checkPromises);
 
+  if (sourceMessage && sourceMessage.type === messageTypes.REACTION) {
+    throw new ServerError('invalid_parameters');
+  }
+
   let { id } = request;
   if (id === null || id === undefined) {
     const ids = await createIDs('threads', 1);
diff --git a/keyserver/src/fetchers/message-fetchers.js b/keyserver/src/fetchers/message-fetchers.js
--- a/keyserver/src/fetchers/message-fetchers.js
+++ b/keyserver/src/fetchers/message-fetchers.js
@@ -681,8 +681,9 @@
     const { rawMessageInfo } = message;
     if (rawMessageInfo.id) {
       invariant(
-        rawMessageInfo.type !== messageTypes.SIDEBAR_SOURCE,
-        'SIDEBAR_SOURCE should not point to a SIDEBAR_SOURCE',
+        rawMessageInfo.type !== messageTypes.SIDEBAR_SOURCE &&
+          rawMessageInfo.type !== messageTypes.REACTION,
+        'SIDEBAR_SOURCE should not point to a SIDEBAR_SOURCE or REACTION',
       );
       messagesByID.set(rawMessageInfo.id, rawMessageInfo);
     }
diff --git a/lib/selectors/chat-selectors.js b/lib/selectors/chat-selectors.js
--- a/lib/selectors/chat-selectors.js
+++ b/lib/selectors/chat-selectors.js
@@ -308,6 +308,11 @@
   let lastMessageInfo = null;
   for (let i = messages.length - 1; i >= 0; i--) {
     const messageInfo = messages[i];
+
+    if (messageInfo.type === messageTypes.REACTION) {
+      continue;
+    }
+
     const originalMessageInfo =
       messageInfo.type === messageTypes.SIDEBAR_SOURCE
         ? messageInfo.sourceMessage
diff --git a/lib/shared/message-utils.js b/lib/shared/message-utils.js
--- a/lib/shared/message-utils.js
+++ b/lib/shared/message-utils.js
@@ -11,6 +11,7 @@
 import {
   type MessageInfo,
   type RawMessageInfo,
+  type ReactionMessageInfo,
   type RobotextMessageInfo,
   type PreviewableMessageInfo,
   type RawMultimediaMessageInfo,
@@ -437,7 +438,10 @@
   | 'individual_viewer';
 
 function getMessageTitle(
-  messageInfo: ComposableMessageInfo | RobotextMessageInfo,
+  messageInfo:
+    | ComposableMessageInfo
+    | RobotextMessageInfo
+    | ReactionMessageInfo,
   threadInfo: ThreadInfo,
   markdownRules: ParserRules,
   viewerContext?: GetMessageTitleViewerContext = 'individual_viewer',
@@ -525,7 +529,10 @@
   threadInfo: ThreadInfo,
   markdownRules: ParserRules,
 ): MessagePreviewResult {
-  const messageInfo: ComposableMessageInfo | RobotextMessageInfo =
+  const messageInfo:
+    | ComposableMessageInfo
+    | RobotextMessageInfo
+    | ReactionMessageInfo =
     originalMessageInfo.type === messageTypes.SIDEBAR_SOURCE
       ? originalMessageInfo.sourceMessage
       : originalMessageInfo;
diff --git a/lib/shared/messages/sidebar-source-message-spec.js b/lib/shared/messages/sidebar-source-message-spec.js
--- a/lib/shared/messages/sidebar-source-message-spec.js
+++ b/lib/shared/messages/sidebar-source-message-spec.js
@@ -108,8 +108,10 @@
       rawMessageInfo.sourceMessage,
     );
     invariant(
-      sourceMessage && sourceMessage.type !== messageTypes.SIDEBAR_SOURCE,
-      'Sidebars can not be created from SIDEBAR SOURCE',
+      sourceMessage &&
+        sourceMessage.type !== messageTypes.SIDEBAR_SOURCE &&
+        sourceMessage.type !== messageTypes.REACTION,
+      'Sidebars can not be created from SIDEBAR SOURCE OR REACTION',
     );
 
     return {
diff --git a/lib/types/message-types.js b/lib/types/message-types.js
--- a/lib/types/message-types.js
+++ b/lib/types/message-types.js
@@ -289,7 +289,8 @@
 export type RawMessageInfo =
   | RawComposableMessageInfo
   | RawRobotextMessageInfo
-  | RawSidebarSourceMessageInfo;
+  | RawSidebarSourceMessageInfo
+  | RawReactionMessageInfo;
 
 export type LocallyComposedMessageInfo =
   | ({
@@ -352,7 +353,8 @@
 export type MessageInfo =
   | ComposableMessageInfo
   | RobotextMessageInfo
-  | SidebarSourceMessageInfo;
+  | SidebarSourceMessageInfo
+  | ReactionMessageInfo;
 
 export type ThreadMessageInfo = {
   messageIDs: string[],
diff --git a/native/chat/message-preview.react.js b/native/chat/message-preview.react.js
--- a/native/chat/message-preview.react.js
+++ b/native/chat/message-preview.react.js
@@ -12,6 +12,7 @@
   messageTypes,
   type MessageType,
   type ComposableMessageInfo,
+  type ReactionMessageInfo,
   type RobotextMessageInfo,
 } from 'lib/types/message-types';
 import { type ThreadInfo } from 'lib/types/thread-types';
@@ -26,7 +27,10 @@
 };
 function MessagePreview(props: Props): React.Node {
   const styles = useStyles(unboundStyles);
-  const messageInfo: ComposableMessageInfo | RobotextMessageInfo =
+  const messageInfo:
+    | ComposableMessageInfo
+    | RobotextMessageInfo
+    | ReactionMessageInfo =
     props.messageInfo.type === messageTypes.SIDEBAR_SOURCE
       ? props.messageInfo.sourceMessage
       : props.messageInfo;