diff --git a/lib/selectors/thread-selectors.js b/lib/selectors/thread-selectors.js
--- a/lib/selectors/thread-selectors.js
+++ b/lib/selectors/thread-selectors.js
@@ -33,6 +33,7 @@
   roleIsAdminRole,
   threadIsPending,
   getPendingThreadID,
+  pendingThreadType,
 } from '../shared/thread-utils.js';
 import type { ClientAvatar, ClientEmojiAvatar } from '../types/avatar-types';
 import type { EntryInfo } from '../types/entry-types.js';
@@ -461,17 +462,28 @@
       const actualMemberIDs = rawThreadInfo.members
         .filter(member => member.role)
         .map(member => member.id);
-      const pendingThreadID = getPendingThreadID(
-        rawThreadInfo.type,
-        actualMemberIDs,
-        rawThreadInfo.sourceMessageID,
-      );
-      const existingResult = result.get(pendingThreadID);
-      if (
-        !existingResult ||
-        rawThreadInfos[existingResult].creationTime > rawThreadInfo.creationTime
-      ) {
-        result.set(pendingThreadID, threadID);
+      // In this function we're generating possible pending thread IDs that
+      // could become `rawThreadInfos`. It is possible that a thick pending
+      // thread becomes a thin thread, so we're including it twice in a map -
+      // for each possible pending thread ID.
+      const possiblePendingThreadTypes = [
+        pendingThreadType(actualMemberIDs.length - 1, 'thin', true),
+        pendingThreadType(actualMemberIDs.length - 1, 'thick', true),
+      ];
+      for (const type of possiblePendingThreadTypes) {
+        const pendingThreadID = getPendingThreadID(
+          type,
+          actualMemberIDs,
+          rawThreadInfo.sourceMessageID,
+        );
+        const existingResult = result.get(pendingThreadID);
+        if (
+          !existingResult ||
+          rawThreadInfos[existingResult].creationTime >
+            rawThreadInfo.creationTime
+        ) {
+          result.set(pendingThreadID, threadID);
+        }
       }
     }
     return result;
diff --git a/lib/shared/thread-actions-utils.js b/lib/shared/thread-actions-utils.js
--- a/lib/shared/thread-actions-utils.js
+++ b/lib/shared/thread-actions-utils.js
@@ -12,6 +12,7 @@
   removeUsersFromThreadActionTypes,
   type RemoveUsersFromThreadInput,
 } from '../actions/thread-actions.js';
+import type { AuxUserInfos } from '../types/aux-user-types.js';
 import type { CalendarQuery } from '../types/entry-types.js';
 import type {
   RelativeMemberInfo,
@@ -23,6 +24,7 @@
   assertThickThreadType,
   threadTypeIsThick,
 } from '../types/thread-types-enum.js';
+import type { ThreadType } from '../types/thread-types-enum.js';
 import type {
   ChangeThreadSettingsPayload,
   ClientNewThinThreadRequest,
@@ -60,6 +62,7 @@
   +handleError?: () => mixed,
   +calendarQuery: CalendarQuery,
   +usingOlmViaTunnelbrokerForDMs: boolean,
+  +auxUserInfos: AuxUserInfos,
 };
 
 async function createRealThreadFromPendingThread({
@@ -71,12 +74,20 @@
   viewerID,
   calendarQuery,
   usingOlmViaTunnelbrokerForDMs,
-}: CreateRealThreadParameters): Promise<string> {
+  auxUserInfos,
+}: CreateRealThreadParameters): Promise<{
+  +threadID: string,
+  +threadType: ThreadType,
+}> {
   if (!threadIsPending(threadInfo.id)) {
-    return threadInfo.id;
+    return {
+      threadID: threadInfo.id,
+      threadType: threadInfo.type,
+    };
   }
 
   let newThreadID;
+  let newThreadType = threadInfo.type;
 
   const otherMemberIDs = threadOtherMembers(threadInfo.members, viewerID).map(
     member => member.id,
@@ -125,7 +136,12 @@
       otherMemberIDs.length > 0,
       'otherMemberIDs should not be empty for threads',
     );
-    if (threadTypeIsThick(threadInfo.type)) {
+    const allUsersSupportThickThreads = otherMemberIDs.every(
+      memberID =>
+        auxUserInfos[memberID]?.deviceList &&
+        auxUserInfos[memberID].deviceList.devices.length > 0,
+    );
+    if (threadTypeIsThick(threadInfo.type) && allUsersSupportThickThreads) {
       const type = assertThickThreadType(
         pendingThreadType(
           otherMemberIDs.length,
@@ -144,6 +160,7 @@
         initialMemberIDs: otherMemberIDs,
         color: threadInfo.color,
       });
+      newThreadType = type;
     } else {
       const type = assertThinThreadType(
         pendingThreadType(
@@ -166,9 +183,13 @@
       void dispatchActionPromise(newThreadActionTypes, resultPromise);
       const result = await resultPromise;
       newThreadID = result.newThreadID;
+      newThreadType = type;
     }
   }
-  return newThreadID;
+  return {
+    threadID: newThreadID,
+    threadType: newThreadType,
+  };
 }
 
 export { removeMemberFromThread, createRealThreadFromPendingThread };
diff --git a/native/input/input-state-container.react.js b/native/input/input-state-container.react.js
--- a/native/input/input-state-container.react.js
+++ b/native/input/input-state-container.react.js
@@ -57,6 +57,7 @@
   threadIsPending,
   threadIsPendingSidebar,
 } from 'lib/shared/thread-utils.js';
+import type { AuxUserInfos } from 'lib/types/aux-user-types';
 import type { CalendarQuery } from 'lib/types/entry-types.js';
 import type {
   Media,
@@ -85,6 +86,7 @@
   threadTypeIsThick,
   threadTypeIsSidebar,
 } from 'lib/types/thread-types-enum.js';
+import type { ThreadType } from 'lib/types/thread-types-enum.js';
 import {
   type ClientNewThinThreadRequest,
   type NewThreadResult,
@@ -170,6 +172,7 @@
   +newThickThread: (request: NewThickThreadRequest) => Promise<string>,
   +textMessageCreationSideEffectsFunc: CreationSideEffectsFunc<RawTextMessageInfo>,
   +usingOlmViaTunnelbrokerForDMs: boolean,
+  +auxUserInfos: AuxUserInfos,
 };
 type State = {
   +pendingUploads: PendingMultimediaUploads,
@@ -185,7 +188,13 @@
     (params: EditInputBarMessageParameters) => void,
   > = [];
   scrollToMessageCallbacks: Array<(messageID: string) => void> = [];
-  pendingThreadCreations: Map<string, Promise<string>> = new Map();
+  pendingThreadCreations: Map<
+    string,
+    Promise<{
+      +threadID: string,
+      +threadType: ThreadType,
+    }>,
+  > = new Map();
   pendingThreadUpdateHandlers: Map<string, (ThreadInfo) => mixed> = new Map();
   // TODO: flip the switch
   // Note that this enables Blob service for encrypted media only
@@ -349,7 +358,8 @@
         // again.
         throw new Error('Thread creation failed');
       }
-      newThreadID = await threadCreationPromise;
+      const result = await threadCreationPromise;
+      newThreadID = result.threadID;
     } catch (e) {
       const copy = cloneError(e);
       copy.localID = messageInfo.localID;
@@ -505,9 +515,9 @@
       }
     }
 
-    let newThreadID = null;
+    let threadCreationResult = null;
     try {
-      newThreadID = await this.startThreadCreation(threadInfo);
+      threadCreationResult = await this.startThreadCreation(threadInfo);
     } catch (e) {
       const copy = cloneError(e);
       copy.localID = messageInfo.localID;
@@ -524,13 +534,14 @@
 
     const newMessageInfo = {
       ...messageInfo,
-      threadID: newThreadID,
+      threadID: threadCreationResult?.threadID,
       time: Date.now(),
     };
 
     const newThreadInfo = {
       ...threadInfo,
-      id: newThreadID,
+      id: threadCreationResult?.threadID,
+      type: threadCreationResult?.threadType ?? threadInfo.type,
     };
 
     void this.props.dispatchActionPromise(
@@ -545,9 +556,14 @@
     );
   };
 
-  startThreadCreation(threadInfo: ThreadInfo): Promise<string> {
+  startThreadCreation(
+    threadInfo: ThreadInfo,
+  ): Promise<{ +threadID: string, +threadType: ThreadType }> {
     if (!threadIsPending(threadInfo.id)) {
-      return Promise.resolve(threadInfo.id);
+      return Promise.resolve({
+        threadID: threadInfo.id,
+        threadType: threadInfo.type,
+      });
     }
     let threadCreationPromise = this.pendingThreadCreations.get(threadInfo.id);
     if (!threadCreationPromise) {
@@ -561,6 +577,7 @@
         viewerID: this.props.viewerID,
         calendarQuery,
         usingOlmViaTunnelbrokerForDMs: this.props.usingOlmViaTunnelbrokerForDMs,
+        auxUserInfos: this.props.auxUserInfos,
       });
       this.pendingThreadCreations.set(threadInfo.id, threadCreationPromise);
     }
@@ -1773,6 +1790,7 @@
     const textMessageCreationSideEffectsFunc =
       useMessageCreationSideEffectsFunc<RawTextMessageInfo>(messageTypes.TEXT);
     const usingOlmViaTunnelbrokerForDMs = useAllowOlmViaTunnelbrokerForDMs();
+    const auxUserInfos = useSelector(state => state.auxUserStore.auxUserInfos);
 
     return (
       <InputStateContainer
@@ -1794,6 +1812,7 @@
         staffCanSee={staffCanSee}
         textMessageCreationSideEffectsFunc={textMessageCreationSideEffectsFunc}
         usingOlmViaTunnelbrokerForDMs={usingOlmViaTunnelbrokerForDMs}
+        auxUserInfos={auxUserInfos}
       />
     );
   });
diff --git a/web/input/input-state-container.react.js b/web/input/input-state-container.react.js
--- a/web/input/input-state-container.react.js
+++ b/web/input/input-state-container.react.js
@@ -59,6 +59,7 @@
   threadIsPending,
   threadIsPendingSidebar,
 } from 'lib/shared/thread-utils.js';
+import type { AuxUserInfos } from 'lib/types/aux-user-types.js';
 import type { CalendarQuery } from 'lib/types/entry-types.js';
 import type {
   MediaMission,
@@ -83,6 +84,7 @@
   threadTypeIsSidebar,
   threadTypeIsThick,
 } from 'lib/types/thread-types-enum.js';
+import type { ThreadType } from 'lib/types/thread-types-enum.js';
 import {
   type ClientNewThinThreadRequest,
   type NewThreadResult,
@@ -170,6 +172,7 @@
   +textMessageCreationSideEffectsFunc: CreationSideEffectsFunc<RawTextMessageInfo>,
   +identityContext: ?IdentityClientContextType,
   +usingOlmViaTunnelbrokerForDMs: boolean,
+  +auxUserInfos: AuxUserInfos,
 };
 type WritableState = {
   pendingUploads: {
@@ -201,9 +204,18 @@
     },
   };
   replyCallbacks: Array<(message: string) => void> = [];
-  pendingThreadCreations: Map<string, Promise<string>> = new Map<
+  pendingThreadCreations: Map<
     string,
-    Promise<string>,
+    Promise<{
+      +threadID: string,
+      +threadType: ThreadType,
+    }>,
+  > = new Map<
+    string,
+    Promise<{
+      +threadID: string,
+      +threadType: ThreadType,
+    }>,
   >();
   // TODO: flip the switch
   // Note that this enables Blob service for encrypted media only
@@ -481,7 +493,8 @@
         // again.
         throw new Error('Thread creation failed');
       }
-      newThreadID = await threadCreationPromise;
+      const result = await threadCreationPromise;
+      newThreadID = result.threadID;
     } catch (e) {
       const copy = cloneError(e);
       copy.localID = messageInfo.localID;
@@ -577,9 +590,15 @@
     }
   }
 
-  startThreadCreation(threadInfo: ThreadInfo): Promise<string> {
+  startThreadCreation(threadInfo: ThreadInfo): Promise<{
+    +threadID: string,
+    +threadType: ThreadType,
+  }> {
     if (!threadIsPending(threadInfo.id)) {
-      return Promise.resolve(threadInfo.id);
+      return Promise.resolve({
+        threadID: threadInfo.id,
+        threadType: threadInfo.type,
+      });
     }
     let threadCreationPromise = this.pendingThreadCreations.get(threadInfo.id);
     if (!threadCreationPromise) {
@@ -593,6 +612,7 @@
         viewerID: this.props.viewerID,
         calendarQuery,
         usingOlmViaTunnelbrokerForDMs: this.props.usingOlmViaTunnelbrokerForDMs,
+        auxUserInfos: this.props.auxUserInfos,
       });
       this.pendingThreadCreations.set(threadInfo.id, threadCreationPromise);
     }
@@ -1323,9 +1343,9 @@
       }
     }
 
-    let newThreadID = null;
+    let threadCreationResult = null;
     try {
-      newThreadID = await this.startThreadCreation(threadInfo);
+      threadCreationResult = await this.startThreadCreation(threadInfo);
     } catch (e) {
       const copy = cloneError(e);
       copy.localID = messageInfo.localID;
@@ -1342,13 +1362,14 @@
 
     const newMessageInfo = {
       ...messageInfo,
-      threadID: newThreadID,
+      threadID: threadCreationResult?.threadID,
       time: Date.now(),
     };
 
     const newThreadInfo = {
       ...threadInfo,
-      id: newThreadID,
+      id: threadCreationResult?.threadID,
+      type: threadCreationResult?.threadType ?? threadInfo.type,
     };
     void this.props.dispatchActionPromise(
       sendTextMessageActionTypes,
@@ -1709,6 +1730,7 @@
     const textMessageCreationSideEffectsFunc =
       useMessageCreationSideEffectsFunc<RawTextMessageInfo>(messageTypes.TEXT);
     const usingOlmViaTunnelbrokerForDMs = useAllowOlmViaTunnelbrokerForDMs();
+    const auxUserInfos = useSelector(state => state.auxUserStore.auxUserInfos);
 
     return (
       <InputStateContainer
@@ -1735,6 +1757,7 @@
         textMessageCreationSideEffectsFunc={textMessageCreationSideEffectsFunc}
         identityContext={identityContext}
         usingOlmViaTunnelbrokerForDMs={usingOlmViaTunnelbrokerForDMs}
+        auxUserInfos={auxUserInfos}
       />
     );
   });