diff --git a/keyserver/src/fetchers/thread-fetchers.js b/keyserver/src/fetchers/thread-fetchers.js
--- a/keyserver/src/fetchers/thread-fetchers.js
+++ b/keyserver/src/fetchers/thread-fetchers.js
@@ -12,11 +12,12 @@
 import { hasMinCodeVersion } from 'lib/shared/version-utils.js';
 import type { AvatarDBContent, ClientAvatar } from 'lib/types/avatar-types.js';
 import type { RawMessageInfo, MessageInfo } from 'lib/types/message-types.js';
+import type { MinimallyEncodedRawThreadInfo } from 'lib/types/minimally-encoded-thread-permissions-types.js';
 import { threadTypes, type ThreadType } from 'lib/types/thread-types-enum.js';
 import {
   type ServerThreadInfo,
   type RawThreadInfos,
-  type RawThreadInfo,
+  type LegacyRawThreadInfo,
 } from 'lib/types/thread-types.js';
 import { ServerError } from 'lib/utils/errors.js';
 
@@ -282,7 +283,9 @@
     { native: 301, web: 56 },
   );
 
-  const threadInfos: { [string]: RawThreadInfo } = {};
+  const threadInfos: {
+    [string]: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo,
+  } = {};
   for (const threadID in serverResult.threadInfos) {
     const serverThreadInfo = serverResult.threadInfos[threadID];
     const threadInfo = rawThreadInfoFromServerThreadInfo(
diff --git a/keyserver/src/shared/state-sync/threads-state-sync-spec.js b/keyserver/src/shared/state-sync/threads-state-sync-spec.js
--- a/keyserver/src/shared/state-sync/threads-state-sync-spec.js
+++ b/keyserver/src/shared/state-sync/threads-state-sync-spec.js
@@ -2,10 +2,11 @@
 
 import { rawThreadInfoValidator } from 'lib/permissions/minimally-encoded-thread-permissions-validators.js';
 import { threadsStateSyncSpec as libSpec } from 'lib/shared/state-sync/threads-state-sync-spec.js';
+import type { MinimallyEncodedRawThreadInfo } from 'lib/types/minimally-encoded-thread-permissions-types.js';
 import type { ClientThreadInconsistencyReportCreationRequest } from 'lib/types/report-types.js';
 import {
-  type RawThreadInfo,
   type RawThreadInfos,
+  type LegacyRawThreadInfo,
 } from 'lib/types/thread-types.js';
 import { hash, combineUnorderedHashes, values } from 'lib/utils/objects.js';
 
@@ -17,7 +18,7 @@
 export const threadsStateSyncSpec: ServerStateSyncSpec<
   RawThreadInfos,
   RawThreadInfos,
-  RawThreadInfo,
+  LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo,
   $ReadOnlyArray<ClientThreadInconsistencyReportCreationRequest>,
 > = Object.freeze({
   fetch,
@@ -44,6 +45,8 @@
   return combineUnorderedHashes(values(infos).map(getServerInfoHash));
 }
 
-function getServerInfoHash(info: RawThreadInfo) {
+function getServerInfoHash(
+  info: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo,
+) {
   return hash(validateOutput(null, rawThreadInfoValidator, info));
 }
diff --git a/lib/hooks/child-threads.js b/lib/hooks/child-threads.js
--- a/lib/hooks/child-threads.js
+++ b/lib/hooks/child-threads.js
@@ -14,7 +14,8 @@
 import { childThreadInfos } from '../selectors/thread-selectors.js';
 import { threadInChatList } from '../shared/thread-utils.js';
 import threadWatcher from '../shared/thread-watcher.js';
-import type { RawThreadInfo, ThreadInfo } from '../types/thread-types.js';
+import type { MinimallyEncodedRawThreadInfo } from '../types/minimally-encoded-thread-permissions-types.js';
+import type { LegacyRawThreadInfo, ThreadInfo } from '../types/thread-types.js';
 import { useDispatchActionPromise } from '../utils/redux-promise-utils.js';
 import { useSelector } from '../utils/redux-utils.js';
 
@@ -40,7 +41,13 @@
   }, [childThreads, predicate]);
 
   const filterSubchannels = React.useCallback(
-    (thread: ?(RawThreadInfo | ThreadInfo)) => {
+    (
+      thread: ?(
+        | LegacyRawThreadInfo
+        | MinimallyEncodedRawThreadInfo
+        | ThreadInfo
+      ),
+    ) => {
       const candidateThreadID = thread?.id;
       if (!candidateThreadID) {
         return false;
diff --git a/lib/hooks/search-threads.js b/lib/hooks/search-threads.js
--- a/lib/hooks/search-threads.js
+++ b/lib/hooks/search-threads.js
@@ -10,10 +10,11 @@
 import { sidebarInfoSelector } from '../selectors/thread-selectors.js';
 import { threadIsChannel } from '../shared/thread-utils.js';
 import type { SetState } from '../types/hook-types.js';
+import type { MinimallyEncodedRawThreadInfo } from '../types/minimally-encoded-thread-permissions-types.js';
 import type {
   SidebarInfo,
-  RawThreadInfo,
   ThreadInfo,
+  LegacyRawThreadInfo,
 } from '../types/thread-types.js';
 import { useSelector } from '../utils/redux-utils.js';
 
@@ -103,8 +104,13 @@
   threadInfo: ThreadInfo,
 ): SearchThreadsResult<ChatThreadItem> {
   const filterFunc = React.useCallback(
-    (thread: ?(ThreadInfo | RawThreadInfo)) =>
-      threadIsChannel(thread) && thread?.parentThreadID === threadInfo.id,
+    (
+      thread: ?(
+        | ThreadInfo
+        | LegacyRawThreadInfo
+        | MinimallyEncodedRawThreadInfo
+      ),
+    ) => threadIsChannel(thread) && thread?.parentThreadID === threadInfo.id,
     [threadInfo.id],
   );
   const childThreadInfos = useFilteredChatListData(filterFunc);
diff --git a/lib/permissions/minimally-encoded-thread-permissions-validators.js b/lib/permissions/minimally-encoded-thread-permissions-validators.js
--- a/lib/permissions/minimally-encoded-thread-permissions-validators.js
+++ b/lib/permissions/minimally-encoded-thread-permissions-validators.js
@@ -22,7 +22,7 @@
   threadCurrentUserInfoValidator,
   legacyThreadInfoValidator,
 } from '../types/thread-types.js';
-import type { RawThreadInfo } from '../types/thread-types.js';
+import type { LegacyRawThreadInfo } from '../types/thread-types.js';
 import { tBool, tID, tShape } from '../utils/validation-utils.js';
 
 const minimallyEncodedRoleInfoValidator: TInterface<MinimallyEncodedRoleInfo> =
@@ -77,7 +77,9 @@
     currentUser: minimallyEncodedThreadCurrentUserInfoValidator,
   });
 
-export const rawThreadInfoValidator: TUnion<RawThreadInfo> = t.union([
+export const rawThreadInfoValidator: TUnion<
+  LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo,
+> = t.union([
   legacyRawThreadInfoValidator,
   minimallyEncodedRawThreadInfoValidator,
 ]);
diff --git a/lib/reducers/integrity-reducer.js b/lib/reducers/integrity-reducer.js
--- a/lib/reducers/integrity-reducer.js
+++ b/lib/reducers/integrity-reducer.js
@@ -10,15 +10,18 @@
 } from '../actions/user-actions.js';
 import type { ThreadStoreOperation } from '../ops/thread-store-ops';
 import type { IntegrityStore } from '../types/integrity-types';
+import type { MinimallyEncodedRawThreadInfo } from '../types/minimally-encoded-thread-permissions-types.js';
 import type { BaseAction } from '../types/redux-types.js';
 import { fullStateSyncActionType } from '../types/socket-types.js';
-import type { RawThreadInfo } from '../types/thread-types.js';
+import type { LegacyRawThreadInfo } from '../types/thread-types.js';
 import { hash } from '../utils/objects.js';
 
 function reduceIntegrityStore(
   state: IntegrityStore,
   action: BaseAction,
-  threadInfos: { +[string]: RawThreadInfo },
+  threadInfos: {
+    +[string]: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo,
+  },
   threadStoreOperations: $ReadOnlyArray<ThreadStoreOperation>,
 ): IntegrityStore {
   if (
diff --git a/lib/reducers/message-reducer.js b/lib/reducers/message-reducer.js
--- a/lib/reducers/message-reducer.js
+++ b/lib/reducers/message-reducer.js
@@ -92,6 +92,7 @@
 } from '../types/message-types.js';
 import type { RawImagesMessageInfo } from '../types/messages/images.js';
 import type { RawMediaMessageInfo } from '../types/messages/media.js';
+import type { MinimallyEncodedRawThreadInfo } from '../types/minimally-encoded-thread-permissions-types.js';
 import { type BaseAction } from '../types/redux-types.js';
 import { processServerRequestsActionType } from '../types/request-types.js';
 import {
@@ -99,7 +100,10 @@
   incrementalStateSyncActionType,
 } from '../types/socket-types.js';
 import { threadPermissions } from '../types/thread-permission-types.js';
-import type { RawThreadInfo, RawThreadInfos } from '../types/thread-types.js';
+import type {
+  LegacyRawThreadInfo,
+  RawThreadInfos,
+} from '../types/thread-types.js';
 import {
   type ClientUpdateInfo,
   processUpdatesActionType,
@@ -127,7 +131,7 @@
 
 function isThreadWatched(
   threadID: string,
-  threadInfo: ?RawThreadInfo,
+  threadInfo: ?LegacyRawThreadInfo | ?MinimallyEncodedRawThreadInfo,
   watchedIDs: $ReadOnlyArray<string>,
 ) {
   return (
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
@@ -35,14 +35,15 @@
   type LocalMessageInfo,
   isComposableMessageType,
 } from '../types/message-types.js';
+import type { MinimallyEncodedRawThreadInfo } from '../types/minimally-encoded-thread-permissions-types.js';
 import type { BaseAppState } from '../types/redux-types.js';
 import { threadTypes } from '../types/thread-types-enum.js';
 import {
-  type RawThreadInfo,
   type SidebarInfo,
   type ThreadInfo,
   maxReadSidebars,
   maxUnreadSidebars,
+  type LegacyRawThreadInfo,
 } from '../types/thread-types.js';
 import type {
   UserInfo,
@@ -227,7 +228,13 @@
 }
 
 function useFilteredChatListData(
-  filterFunction: (threadInfo: ?(ThreadInfo | RawThreadInfo)) => boolean,
+  filterFunction: (
+    threadInfo: ?(
+      | ThreadInfo
+      | LegacyRawThreadInfo
+      | MinimallyEncodedRawThreadInfo
+    ),
+  ) => boolean,
 ): $ReadOnlyArray<ChatThreadItem> {
   const threadInfos = useSelector(threadInfoSelector);
   const messageInfos = useSelector(messageInfoSelector);
@@ -252,7 +259,13 @@
   messageStore: MessageStore,
   messageInfos: { +[id: string]: ?MessageInfo },
   sidebarInfos: { +[id: string]: $ReadOnlyArray<SidebarInfo> },
-  filterFunction: (threadInfo: ?(ThreadInfo | RawThreadInfo)) => boolean,
+  filterFunction: (
+    threadInfo: ?(
+      | ThreadInfo
+      | LegacyRawThreadInfo
+      | MinimallyEncodedRawThreadInfo
+    ),
+  ) => boolean,
 ): $ReadOnlyArray<ChatThreadItem> {
   return _flow(
     _filter(filterFunction),
diff --git a/lib/selectors/nav-selectors.js b/lib/selectors/nav-selectors.js
--- a/lib/selectors/nav-selectors.js
+++ b/lib/selectors/nav-selectors.js
@@ -12,12 +12,13 @@
   defaultCalendarQuery,
 } from '../types/entry-types.js';
 import type { CalendarFilter } from '../types/filter-types.js';
+import type { MinimallyEncodedRawThreadInfo } from '../types/minimally-encoded-thread-permissions-types.js';
 import type { BaseNavInfo } from '../types/nav-types.js';
 import type { BaseAppState } from '../types/redux-types.js';
 import type {
   RelativeMemberInfo,
-  RawThreadInfo,
   ThreadInfo,
+  LegacyRawThreadInfo,
 } from '../types/thread-types';
 import type { UserInfo } from '../types/user-types.js';
 import { getConfig } from '../utils/config.js';
@@ -120,7 +121,9 @@
 }
 
 function useThreadSearchIndex(
-  threadInfos: $ReadOnlyArray<RawThreadInfo | ThreadInfo>,
+  threadInfos: $ReadOnlyArray<
+    LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo | ThreadInfo,
+  >,
 ): SearchIndex {
   const userInfos = useSelector(state => state.userStore.userInfos);
   const viewerID = useSelector(
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
@@ -39,6 +39,7 @@
 import type { ClientAvatar, ClientEmojiAvatar } from '../types/avatar-types';
 import type { EntryInfo } from '../types/entry-types.js';
 import type { MessageStore, RawMessageInfo } from '../types/message-types.js';
+import type { MinimallyEncodedRawThreadInfo } from '../types/minimally-encoded-thread-permissions-types.js';
 import type { BaseAppState } from '../types/redux-types.js';
 import { threadPermissions } from '../types/thread-permission-types.js';
 import {
@@ -50,8 +51,8 @@
   SidebarInfo,
   RelativeMemberInfo,
   ThreadInfo,
-  RawThreadInfo,
   RawThreadInfos,
+  LegacyRawThreadInfo,
 } from '../types/thread-types.js';
 import { dateString, dateFromString } from '../utils/date-utils.js';
 import { values } from '../utils/objects.js';
@@ -343,7 +344,7 @@
     (state: BaseAppState<>) => state.threadStore.threadInfos[threadID],
     relativeMemberInfoSelectorForMembersOfThread(threadID),
     (
-      threadInfo: ?RawThreadInfo,
+      threadInfo: ?LegacyRawThreadInfo | ?MinimallyEncodedRawThreadInfo,
       members: $ReadOnlyArray<RelativeMemberInfo>,
     ): boolean => {
       if (!threadInfo) {
diff --git a/lib/shared/avatar-utils.js b/lib/shared/avatar-utils.js
--- a/lib/shared/avatar-utils.js
+++ b/lib/shared/avatar-utils.js
@@ -16,8 +16,9 @@
   ResolvedClientAvatar,
   GenericUserInfoWithAvatar,
 } from '../types/avatar-types.js';
+import type { MinimallyEncodedRawThreadInfo } from '../types/minimally-encoded-thread-permissions-types.js';
 import { threadTypes } from '../types/thread-types-enum.js';
-import type { RawThreadInfo, ThreadInfo } from '../types/thread-types.js';
+import type { LegacyRawThreadInfo, ThreadInfo } from '../types/thread-types.js';
 import type { UserInfos } from '../types/user-types.js';
 import { useSelector } from '../utils/redux-utils.js';
 import { ashoatKeyserverID } from '../utils/validation-utils.js';
@@ -270,7 +271,7 @@
 }
 
 function getUserAvatarForThread(
-  threadInfo: RawThreadInfo | ThreadInfo,
+  threadInfo: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo | ThreadInfo,
   viewerID: ?string,
   userInfos: UserInfos,
 ): ClientAvatar {
@@ -296,7 +297,7 @@
 }
 
 function getAvatarForThread(
-  thread: RawThreadInfo | ThreadInfo,
+  thread: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo | ThreadInfo,
   containingThreadInfo: ?ThreadInfo,
 ): ClientAvatar {
   if (thread.avatar) {
@@ -312,7 +313,9 @@
   return getDefaultAvatar(thread.id, thread.color);
 }
 
-function useAvatarForThread(thread: RawThreadInfo | ThreadInfo): ClientAvatar {
+function useAvatarForThread(
+  thread: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo | ThreadInfo,
+): ClientAvatar {
   const containingThreadID = thread.containingThreadID;
   const containingThreadInfo = useSelector(state =>
     containingThreadID ? threadInfoSelector(state)[containingThreadID] : null,
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
@@ -42,7 +42,8 @@
   RawReactionMessageInfo,
   ReactionMessageInfo,
 } from '../types/messages/reaction.js';
-import type { RawThreadInfo, ThreadInfo } from '../types/thread-types.js';
+import type { MinimallyEncodedRawThreadInfo } from '../types/minimally-encoded-thread-permissions-types.js';
+import type { LegacyRawThreadInfo, ThreadInfo } from '../types/thread-types.js';
 import type { UserInfos } from '../types/user-types.js';
 import {
   type EntityText,
@@ -680,7 +681,7 @@
 
 function isInvalidPinSourceForThread(
   messageInfo: RawMessageInfo | MessageInfo,
-  threadInfo: RawThreadInfo | ThreadInfo,
+  threadInfo: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo | ThreadInfo,
 ): boolean {
   const isValidPinSource = !isInvalidPinSource(messageInfo);
   const isFirstMessageInSidebar = threadInfo.sourceMessageID === messageInfo.id;
diff --git a/lib/shared/state-sync/threads-state-sync-spec.js b/lib/shared/state-sync/threads-state-sync-spec.js
--- a/lib/shared/state-sync/threads-state-sync-spec.js
+++ b/lib/shared/state-sync/threads-state-sync-spec.js
@@ -4,6 +4,7 @@
 import { createSelector } from 'reselect';
 
 import type { StateSyncSpec, BoundStateSyncSpec } from './state-sync-spec.js';
+import type { MinimallyEncodedRawThreadInfo } from '../../types/minimally-encoded-thread-permissions-types.js';
 import type { AppState } from '../../types/redux-types.js';
 import {
   reportTypes,
@@ -11,8 +12,8 @@
 } from '../../types/report-types.js';
 import type { ProcessServerRequestAction } from '../../types/request-types.js';
 import {
-  type RawThreadInfo,
   type RawThreadInfos,
+  type LegacyRawThreadInfo,
 } from '../../types/thread-types.js';
 import { actionLogger } from '../../utils/action-logger.js';
 import { getConfig } from '../../utils/config.js';
@@ -25,7 +26,7 @@
   state: AppState,
 ) => BoundStateSyncSpec<
   RawThreadInfos,
-  RawThreadInfo,
+  LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo,
   $ReadOnlyArray<ClientThreadInconsistencyReportCreationRequest>,
 > = createSelector(
   (state: AppState) => state.integrityStore.threadHashes,
@@ -44,7 +45,7 @@
 
 export const threadsStateSyncSpec: StateSyncSpec<
   RawThreadInfos,
-  RawThreadInfo,
+  LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo,
   $ReadOnlyArray<ClientThreadInconsistencyReportCreationRequest>,
 > = Object.freeze({
   hashKey: 'threadInfos',
diff --git a/lib/shared/thread-utils.js b/lib/shared/thread-utils.js
--- a/lib/shared/thread-utils.js
+++ b/lib/shared/thread-utils.js
@@ -96,7 +96,6 @@
   ChangeThreadSettingsPayload,
   UserProfileThreadInfo,
   RelativeMemberInfo,
-  RawThreadInfo,
   ThreadInfo,
   RawThreadInfos,
 } from '../types/thread-types.js';
@@ -128,7 +127,11 @@
 import { pendingThreadIDRegex } from '../utils/validation-utils.js';
 
 function threadHasPermission(
-  threadInfo: ?(ThreadInfo | RawThreadInfo),
+  threadInfo: ?(
+    | ThreadInfo
+    | LegacyRawThreadInfo
+    | MinimallyEncodedRawThreadInfo
+  ),
   permission: ThreadPermission,
 ): boolean {
   if (!threadInfo) {
@@ -145,7 +148,13 @@
   return permissionLookup(threadInfo.currentUser.permissions, permission);
 }
 
-function viewerIsMember(threadInfo: ?(RawThreadInfo | ThreadInfo)): boolean {
+function viewerIsMember(
+  threadInfo: ?(
+    | LegacyRawThreadInfo
+    | MinimallyEncodedRawThreadInfo
+    | ThreadInfo
+  ),
+): boolean {
   return !!(
     threadInfo &&
     threadInfo.currentUser.role !== null &&
@@ -153,38 +162,76 @@
   );
 }
 
-function threadIsInHome(threadInfo: ?(RawThreadInfo | ThreadInfo)): boolean {
+function threadIsInHome(
+  threadInfo: ?(
+    | LegacyRawThreadInfo
+    | MinimallyEncodedRawThreadInfo
+    | ThreadInfo
+  ),
+): boolean {
   return !!(threadInfo && threadInfo.currentUser.subscription.home);
 }
 
 // Can have messages
-function threadInChatList(threadInfo: ?(RawThreadInfo | ThreadInfo)): boolean {
+function threadInChatList(
+  threadInfo: ?(
+    | LegacyRawThreadInfo
+    | MinimallyEncodedRawThreadInfo
+    | ThreadInfo
+  ),
+): boolean {
   return (
     viewerIsMember(threadInfo) &&
     threadHasPermission(threadInfo, threadPermissions.VISIBLE)
   );
 }
 
-function threadIsTopLevel(threadInfo: ?(RawThreadInfo | ThreadInfo)): boolean {
+function threadIsTopLevel(
+  threadInfo: ?(
+    | LegacyRawThreadInfo
+    | MinimallyEncodedRawThreadInfo
+    | ThreadInfo
+  ),
+): boolean {
   return threadInChatList(threadInfo) && threadIsChannel(threadInfo);
 }
 
-function threadIsChannel(threadInfo: ?(RawThreadInfo | ThreadInfo)): boolean {
+function threadIsChannel(
+  threadInfo: ?(
+    | LegacyRawThreadInfo
+    | MinimallyEncodedRawThreadInfo
+    | ThreadInfo
+  ),
+): boolean {
   return !!(threadInfo && threadInfo.type !== threadTypes.SIDEBAR);
 }
 
-function threadIsSidebar(threadInfo: ?(RawThreadInfo | ThreadInfo)): boolean {
+function threadIsSidebar(
+  threadInfo: ?(
+    | LegacyRawThreadInfo
+    | MinimallyEncodedRawThreadInfo
+    | ThreadInfo
+  ),
+): boolean {
   return threadInfo?.type === threadTypes.SIDEBAR;
 }
 
 function threadInBackgroundChatList(
-  threadInfo: ?(RawThreadInfo | ThreadInfo),
+  threadInfo: ?(
+    | LegacyRawThreadInfo
+    | MinimallyEncodedRawThreadInfo
+    | ThreadInfo
+  ),
 ): boolean {
   return threadInChatList(threadInfo) && !threadIsInHome(threadInfo);
 }
 
 function threadInHomeChatList(
-  threadInfo: ?(RawThreadInfo | ThreadInfo),
+  threadInfo: ?(
+    | LegacyRawThreadInfo
+    | MinimallyEncodedRawThreadInfo
+    | ThreadInfo
+  ),
 ): boolean {
   return threadInChatList(threadInfo) && threadIsInHome(threadInfo);
 }
@@ -192,7 +239,11 @@
 // Can have Calendar entries,
 // does appear as a top-level entity in the thread list
 function threadInFilterList(
-  threadInfo: ?(RawThreadInfo | ThreadInfo),
+  threadInfo: ?(
+    | LegacyRawThreadInfo
+    | MinimallyEncodedRawThreadInfo
+    | ThreadInfo
+  ),
 ): boolean {
   return (
     threadInChatList(threadInfo) &&
@@ -202,7 +253,11 @@
 }
 
 function userIsMember(
-  threadInfo: ?(RawThreadInfo | ThreadInfo),
+  threadInfo: ?(
+    | LegacyRawThreadInfo
+    | MinimallyEncodedRawThreadInfo
+    | ThreadInfo
+  ),
   userID: string,
 ): boolean {
   if (!threadInfo) {
@@ -231,9 +286,9 @@
   );
 }
 
-function threadMembersWithoutAddedAshoat<T: RawThreadInfo | ThreadInfo>(
-  threadInfo: T,
-): $PropertyType<T, 'members'> {
+function threadMembersWithoutAddedAshoat<
+  T: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo | ThreadInfo,
+>(threadInfo: T): $PropertyType<T, 'members'> {
   if (threadInfo.community !== genesis.id) {
     return threadInfo.members;
   }
@@ -247,7 +302,7 @@
 }
 
 function threadOrParentThreadIsGroupChat(
-  threadInfo: RawThreadInfo | ThreadInfo,
+  threadInfo: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo | ThreadInfo,
 ) {
   return threadMembersWithoutAddedAshoat(threadInfo).length > 2;
 }
@@ -261,7 +316,7 @@
 }
 
 function getSingleOtherUser(
-  threadInfo: RawThreadInfo | ThreadInfo,
+  threadInfo: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo | ThreadInfo,
   viewerID: ?string,
 ): ?string {
   if (!viewerID) {
@@ -742,7 +797,7 @@
   serverThreadInfo: ServerThreadInfo,
   viewerID: string,
   options?: RawThreadInfoOptions,
-): ?RawThreadInfo {
+): ?LegacyRawThreadInfo | ?MinimallyEncodedRawThreadInfo {
   const filterThreadEditAvatarPermission =
     options?.filterThreadEditAvatarPermission;
   const excludePinInfo = options?.excludePinInfo;
@@ -895,7 +950,7 @@
 }
 
 function threadInfoFromRawThreadInfo(
-  rawThreadInfo: RawThreadInfo,
+  rawThreadInfo: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo,
   viewerID: ?string,
   userInfos: UserInfos,
 ): MinimallyEncodedThreadInfo {
@@ -1010,7 +1065,7 @@
 }
 
 function threadIsWithBlockedUserOnly(
-  threadInfo: RawThreadInfo | ThreadInfo,
+  threadInfo: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo | ThreadInfo,
   viewerID: ?string,
   userInfos: UserInfos,
   checkOnlyViewerBlock?: boolean,
@@ -1042,7 +1097,7 @@
 }
 
 function threadFrozenDueToBlock(
-  threadInfo: RawThreadInfo | ThreadInfo,
+  threadInfo: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo | ThreadInfo,
   viewerID: ?string,
   userInfos: UserInfos,
 ): boolean {
@@ -1050,7 +1105,7 @@
 }
 
 function threadFrozenDueToViewerBlock(
-  threadInfo: RawThreadInfo | ThreadInfo,
+  threadInfo: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo | ThreadInfo,
   viewerID: ?string,
   userInfos: UserInfos,
 ): boolean {
@@ -1066,7 +1121,7 @@
 
 function memberIsAdmin(
   memberInfo: RelativeMemberInfo | MemberInfo,
-  threadInfo: RawThreadInfo | ThreadInfo,
+  threadInfo: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo | ThreadInfo,
 ): boolean {
   return !!(
     memberInfo.role && roleIsAdminRole(threadInfo.roles[memberInfo.role])
@@ -1089,7 +1144,12 @@
 }
 
 function threadHasAdminRole(
-  threadInfo: ?(RawThreadInfo | ThreadInfo | ServerThreadInfo),
+  threadInfo: ?(
+    | LegacyRawThreadInfo
+    | MinimallyEncodedRawThreadInfo
+    | ThreadInfo
+    | ServerThreadInfo
+  ),
 ): boolean {
   if (!threadInfo) {
     return false;
@@ -1098,7 +1158,7 @@
 }
 
 function threadOrParentThreadHasAdminRole(
-  threadInfo: RawThreadInfo | ThreadInfo,
+  threadInfo: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo | ThreadInfo,
 ) {
   return (
     threadMembersWithoutAddedAshoat(threadInfo).filter(member =>
@@ -1346,7 +1406,11 @@
 }
 
 function threadMemberHasPermission(
-  threadInfo: ServerThreadInfo | RawThreadInfo | ThreadInfo,
+  threadInfo:
+    | ServerThreadInfo
+    | LegacyRawThreadInfo
+    | MinimallyEncodedRawThreadInfo
+    | ThreadInfo,
   memberID: string,
   permission: ThreadPermission,
 ): boolean {
@@ -1425,7 +1489,11 @@
 }
 
 function getContainingThreadID(
-  parentThreadInfo: ?ServerThreadInfo | RawThreadInfo | ThreadInfo,
+  parentThreadInfo:
+    | ?ServerThreadInfo
+    | LegacyRawThreadInfo
+    | MinimallyEncodedRawThreadInfo
+    | ThreadInfo,
   threadType: ThreadType,
 ): ?string {
   if (!parentThreadInfo) {
@@ -1441,7 +1509,11 @@
 }
 
 function getCommunity(
-  parentThreadInfo: ?ServerThreadInfo | RawThreadInfo | ThreadInfo,
+  parentThreadInfo:
+    | ?ServerThreadInfo
+    | LegacyRawThreadInfo
+    | MinimallyEncodedRawThreadInfo
+    | ThreadInfo,
 ): ?string {
   if (!parentThreadInfo) {
     return null;
@@ -1633,7 +1705,7 @@
 }
 
 function threadInfoInsideCommunity(
-  threadInfo: RawThreadInfo | ThreadInfo,
+  threadInfo: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo | ThreadInfo,
   communityID: string,
 ): boolean {
   return threadInfo.community === communityID || threadInfo.id === communityID;
@@ -1715,14 +1787,16 @@
   }, [threadInfo]);
 }
 
-function communityOrThreadNoun(threadInfo: RawThreadInfo | ThreadInfo): string {
+function communityOrThreadNoun(
+  threadInfo: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo | ThreadInfo,
+): string {
   return threadTypeIsCommunityRoot(threadInfo.type)
     ? 'community'
     : threadNoun(threadInfo.type, threadInfo.parentThreadID);
 }
 
 function getThreadsToDeleteText(
-  threadInfo: RawThreadInfo | ThreadInfo,
+  threadInfo: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo | ThreadInfo,
 ): string {
   return `${
     threadTypeIsCommunityRoot(threadInfo.type)
diff --git a/lib/shared/user-utils.js b/lib/shared/user-utils.js
--- a/lib/shared/user-utils.js
+++ b/lib/shared/user-utils.js
@@ -2,8 +2,9 @@
 
 import { memberHasAdminPowers } from './thread-utils.js';
 import { useENSNames } from '../hooks/ens-cache.js';
+import type { MinimallyEncodedRawThreadInfo } from '../types/minimally-encoded-thread-permissions-types.js';
 import type {
-  RawThreadInfo,
+  LegacyRawThreadInfo,
   ServerThreadInfo,
   ThreadInfo,
 } from '../types/thread-types.js';
@@ -33,7 +34,11 @@
 }
 
 function useKeyserverAdmin(
-  community: ThreadInfo | RawThreadInfo | ServerThreadInfo,
+  community:
+    | ThreadInfo
+    | LegacyRawThreadInfo
+    | MinimallyEncodedRawThreadInfo
+    | ServerThreadInfo,
 ): ?UserInfo {
   const userInfos = useSelector(state => state.userStore.userInfos);
   // This hack only works as long as there is only one admin
diff --git a/lib/types/request-types.js b/lib/types/request-types.js
--- a/lib/types/request-types.js
+++ b/lib/types/request-types.js
@@ -19,7 +19,7 @@
   ClientThreadInconsistencyReportShape,
   ClientEntryInconsistencyReportShape,
 } from './report-types.js';
-import { type RawThreadInfo } from './thread-types.js';
+import type { LegacyRawThreadInfo } from './thread-types.js';
 import {
   type CurrentUserInfo,
   currentUserInfoValidator,
@@ -104,7 +104,7 @@
 }>;
 
 type StateChanges = Partial<{
-  +rawThreadInfos: RawThreadInfo[],
+  +rawThreadInfos: LegacyRawThreadInfo[] | MinimallyEncodedRawThreadInfo[],
   +rawEntryInfos: RawEntryInfo[],
   +currentUserInfo: CurrentUserInfo,
   +userInfos: AccountUserInfo[],
diff --git a/lib/types/thread-types.js b/lib/types/thread-types.js
--- a/lib/types/thread-types.js
+++ b/lib/types/thread-types.js
@@ -144,9 +144,8 @@
     pinnedCount: t.maybe(t.Number),
   });
 
-export type RawThreadInfo = LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo;
 export type RawThreadInfos = {
-  +[id: string]: RawThreadInfo,
+  +[id: string]: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo,
 };
 export type MinimallyEncodedRawThreadInfos = {
   +[id: string]: MinimallyEncodedRawThreadInfo,
@@ -451,14 +450,14 @@
 export type RoleModificationRequest = CreateRoleAction | EditRoleAction;
 
 export type RoleModificationResult = {
-  +threadInfo: RawThreadInfo,
+  +threadInfo: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo,
   +updatesResult: {
     +newUpdates: $ReadOnlyArray<ServerUpdateInfo>,
   },
 };
 
 export type RoleModificationPayload = {
-  +threadInfo: RawThreadInfo,
+  +threadInfo: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo,
   +updatesResult: {
     +newUpdates: $ReadOnlyArray<ClientUpdateInfo>,
   },
@@ -470,14 +469,14 @@
 };
 
 export type RoleDeletionResult = {
-  +threadInfo: RawThreadInfo,
+  +threadInfo: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo,
   +updatesResult: {
     +newUpdates: $ReadOnlyArray<ServerUpdateInfo>,
   },
 };
 
 export type RoleDeletionPayload = {
-  +threadInfo: RawThreadInfo,
+  +threadInfo: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo,
   +updatesResult: {
     +newUpdates: $ReadOnlyArray<ClientUpdateInfo>,
   },
diff --git a/lib/types/update-types.js b/lib/types/update-types.js
--- a/lib/types/update-types.js
+++ b/lib/types/update-types.js
@@ -7,7 +7,8 @@
   type RawMessageInfo,
   type MessageTruncationStatus,
 } from './message-types.js';
-import type { RawThreadInfo } from './thread-types.js';
+import type { MinimallyEncodedRawThreadInfo } from './minimally-encoded-thread-permissions-types.js';
+import type { LegacyRawThreadInfo } from './thread-types.js';
 import {
   type UserInfo,
   userInfoValidator,
@@ -183,7 +184,7 @@
   +type: 1,
   +id: string,
   +time: number,
-  +threadInfo: RawThreadInfo,
+  +threadInfo: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo,
 };
 
 export type ThreadReadStatusUpdateInfo = {
@@ -205,7 +206,7 @@
   +type: 4,
   +id: string,
   +time: number,
-  +threadInfo: RawThreadInfo,
+  +threadInfo: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo,
   +rawMessageInfos: $ReadOnlyArray<RawMessageInfo>,
   +truncationStatus: MessageTruncationStatus,
   +rawEntryInfos: $ReadOnlyArray<RawEntryInfo>,
diff --git a/lib/utils/drawer-utils.react.js b/lib/utils/drawer-utils.react.js
--- a/lib/utils/drawer-utils.react.js
+++ b/lib/utils/drawer-utils.react.js
@@ -4,9 +4,10 @@
 
 import { values } from './objects.js';
 import { threadInFilterList, threadIsChannel } from '../shared/thread-utils.js';
+import type { MinimallyEncodedRawThreadInfo } from '../types/minimally-encoded-thread-permissions-types.js';
 import { communitySubthreads } from '../types/thread-types-enum.js';
 import type {
-  RawThreadInfo,
+  LegacyRawThreadInfo,
   ResolvedThreadInfo,
   ThreadInfo,
 } from '../types/thread-types.js';
@@ -104,7 +105,10 @@
 function filterThreadIDsBelongingToCommunity(
   communityID: string,
   threadInfosObj: {
-    +[id: string]: RawThreadInfo | ThreadInfo,
+    +[id: string]:
+      | LegacyRawThreadInfo
+      | MinimallyEncodedRawThreadInfo
+      | ThreadInfo,
   },
 ): $ReadOnlySet<string> {
   const threadInfos = values(threadInfosObj);
diff --git a/lib/utils/entity-text.js b/lib/utils/entity-text.js
--- a/lib/utils/entity-text.js
+++ b/lib/utils/entity-text.js
@@ -9,12 +9,13 @@
 import { useENSNames, type UseENSNamesOptions } from '../hooks/ens-cache.js';
 import { threadNoun } from '../shared/thread-utils.js';
 import { stringForUser } from '../shared/user-utils.js';
+import type { MinimallyEncodedRawThreadInfo } from '../types/minimally-encoded-thread-permissions-types.js';
 import {
   type ThreadType,
   threadTypes,
   threadTypeValidator,
 } from '../types/thread-types-enum.js';
-import type { RawThreadInfo, ThreadInfo } from '../types/thread-types.js';
+import type { LegacyRawThreadInfo, ThreadInfo } from '../types/thread-types.js';
 import { basePluralize } from '../utils/text-utils.js';
 
 export type UserEntity = {
@@ -138,13 +139,19 @@
     }
   | {
       +display?: 'shortName',
-      +threadInfo: RawThreadInfo | ThreadInfo,
+      +threadInfo:
+        | LegacyRawThreadInfo
+        | MinimallyEncodedRawThreadInfo
+        | ThreadInfo,
       +subchannel?: ?boolean,
       +possessive?: ?boolean,
     }
   | {
       +display: 'alwaysDisplayShortName',
-      +threadInfo: RawThreadInfo | ThreadInfo,
+      +threadInfo:
+        | LegacyRawThreadInfo
+        | MinimallyEncodedRawThreadInfo
+        | ThreadInfo,
       +possessive?: ?boolean,
     }
   | {
diff --git a/lib/utils/message-pinning-utils.js b/lib/utils/message-pinning-utils.js
--- a/lib/utils/message-pinning-utils.js
+++ b/lib/utils/message-pinning-utils.js
@@ -3,12 +3,13 @@
 import { isInvalidPinSourceForThread } from '../shared/message-utils.js';
 import { threadHasPermission } from '../shared/thread-utils.js';
 import type { RawMessageInfo, MessageInfo } from '../types/message-types.js';
+import type { MinimallyEncodedRawThreadInfo } from '../types/minimally-encoded-thread-permissions-types.js';
 import { threadPermissions } from '../types/thread-permission-types.js';
-import type { RawThreadInfo, ThreadInfo } from '../types/thread-types.js';
+import type { LegacyRawThreadInfo, ThreadInfo } from '../types/thread-types.js';
 
 function canToggleMessagePin(
   messageInfo: RawMessageInfo | MessageInfo,
-  threadInfo: RawThreadInfo | ThreadInfo,
+  threadInfo: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo | ThreadInfo,
 ): boolean {
   const isValidMessage = !isInvalidPinSourceForThread(messageInfo, threadInfo);
   const hasManagePinsPermission = threadHasPermission(
diff --git a/lib/utils/thread-ops-utils.js b/lib/utils/thread-ops-utils.js
--- a/lib/utils/thread-ops-utils.js
+++ b/lib/utils/thread-ops-utils.js
@@ -24,12 +24,11 @@
   legacyMemberInfoValidator,
   type LegacyRawThreadInfo,
   legacyRoleInfoValidator,
-  type RawThreadInfo,
   threadCurrentUserInfoValidator,
 } from '../types/thread-types.js';
 
 function convertRawThreadInfoToClientDBThreadInfo(
-  rawThreadInfo: RawThreadInfo,
+  rawThreadInfo: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo,
 ): ClientDBThreadInfo {
   const { minimallyEncoded, ...rest } = rawThreadInfo;
   return {
diff --git a/native/avatars/edit-thread-avatar.react.js b/native/avatars/edit-thread-avatar.react.js
--- a/native/avatars/edit-thread-avatar.react.js
+++ b/native/avatars/edit-thread-avatar.react.js
@@ -6,7 +6,11 @@
 import { ActivityIndicator, TouchableOpacity, View } from 'react-native';
 
 import { EditThreadAvatarContext } from 'lib/components/base-edit-thread-avatar-provider.react.js';
-import type { RawThreadInfo, ThreadInfo } from 'lib/types/thread-types.js';
+import type { MinimallyEncodedRawThreadInfo } from 'lib/types/minimally-encoded-thread-permissions-types.js';
+import type {
+  LegacyRawThreadInfo,
+  ThreadInfo,
+} from 'lib/types/thread-types.js';
 
 import {
   useNativeSetThreadAvatar,
@@ -22,7 +26,7 @@
 import { useStyles } from '../themes/colors.js';
 
 type Props = {
-  +threadInfo: RawThreadInfo | ThreadInfo,
+  +threadInfo: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo | ThreadInfo,
   +disabled?: boolean,
 };
 function EditThreadAvatar(props: Props): React.Node {
diff --git a/native/avatars/thread-avatar.react.js b/native/avatars/thread-avatar.react.js
--- a/native/avatars/thread-avatar.react.js
+++ b/native/avatars/thread-avatar.react.js
@@ -8,9 +8,10 @@
 } from 'lib/shared/avatar-utils.js';
 import { getSingleOtherUser } from 'lib/shared/thread-utils.js';
 import type { AvatarSize } from 'lib/types/avatar-types.js';
+import type { MinimallyEncodedRawThreadInfo } from 'lib/types/minimally-encoded-thread-permissions-types.js';
 import { threadTypes } from 'lib/types/thread-types-enum.js';
 import type {
-  RawThreadInfo,
+  LegacyRawThreadInfo,
   ResolvedThreadInfo,
   ThreadInfo,
 } from 'lib/types/thread-types.js';
@@ -19,7 +20,11 @@
 import { useSelector } from '../redux/redux-utils.js';
 
 type Props = {
-  +threadInfo: RawThreadInfo | ThreadInfo | ResolvedThreadInfo,
+  +threadInfo:
+    | LegacyRawThreadInfo
+    | MinimallyEncodedRawThreadInfo
+    | ThreadInfo
+    | ResolvedThreadInfo,
   +size: AvatarSize,
 };
 
diff --git a/native/chat/settings/emoji-thread-avatar-creation.react.js b/native/chat/settings/emoji-thread-avatar-creation.react.js
--- a/native/chat/settings/emoji-thread-avatar-creation.react.js
+++ b/native/chat/settings/emoji-thread-avatar-creation.react.js
@@ -6,7 +6,11 @@
 import { EditThreadAvatarContext } from 'lib/components/base-edit-thread-avatar-provider.react.js';
 import { savedEmojiAvatarSelectorForThread } from 'lib/selectors/thread-selectors.js';
 import type { UpdateUserAvatarRequest } from 'lib/types/avatar-types.js';
-import type { RawThreadInfo, ThreadInfo } from 'lib/types/thread-types.js';
+import type { MinimallyEncodedRawThreadInfo } from 'lib/types/minimally-encoded-thread-permissions-types.js';
+import type {
+  LegacyRawThreadInfo,
+  ThreadInfo,
+} from 'lib/types/thread-types.js';
 
 import { useNativeSetThreadAvatar } from '../../avatars/avatar-hooks.js';
 import EmojiAvatarCreation from '../../avatars/emoji-avatar-creation.react.js';
@@ -16,7 +20,7 @@
 import { useSelector } from '../../redux/redux-utils.js';
 
 export type EmojiThreadAvatarCreationParams = {
-  +threadInfo: RawThreadInfo | ThreadInfo,
+  +threadInfo: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo | ThreadInfo,
 };
 
 type Props = {
diff --git a/native/redux/client-db-utils.js b/native/redux/client-db-utils.js
--- a/native/redux/client-db-utils.js
+++ b/native/redux/client-db-utils.js
@@ -7,9 +7,10 @@
   ClientDBMessageInfo,
   ClientDBThreadMessageInfo,
 } from 'lib/types/message-types.js';
+import type { MinimallyEncodedRawThreadInfo } from 'lib/types/minimally-encoded-thread-permissions-types.js';
 import type {
   ClientDBThreadInfo,
-  RawThreadInfo,
+  LegacyRawThreadInfo,
   RawThreadInfos,
 } from 'lib/types/thread-types.js';
 import {
@@ -71,7 +72,10 @@
 
   // Convert `rawThreadInfo`s to a map of `threadID` => `threadInfo`.
   const threadIDToThreadInfo = rawThreadInfos.reduce(
-    (acc: { [string]: RawThreadInfo }, threadInfo: RawThreadInfo) => {
+    (
+      acc: { [string]: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo },
+      threadInfo: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo,
+    ) => {
       acc[threadInfo.id] = threadInfo;
       return acc;
     },
@@ -82,9 +86,9 @@
   const updatedThreadIDToThreadInfo = migrationFunc(threadIDToThreadInfo);
 
   // Convert the updated `threadInfo`s back into an array.
-  const updatedRawThreadInfos: $ReadOnlyArray<RawThreadInfo> = values(
-    updatedThreadIDToThreadInfo,
-  );
+  const updatedRawThreadInfos: $ReadOnlyArray<
+    LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo,
+  > = values(updatedThreadIDToThreadInfo);
 
   // Translate `RawThreadInfo`s to `ClientDBThreadInfo`s.
   const convertedClientDBThreadInfos: $ReadOnlyArray<ClientDBThreadInfo> =
diff --git a/native/redux/persist.js b/native/redux/persist.js
--- a/native/redux/persist.js
+++ b/native/redux/persist.js
@@ -63,6 +63,7 @@
   type RawMessageInfo,
 } from 'lib/types/message-types.js';
 import { minimallyEncodeRawThreadInfo } from 'lib/types/minimally-encoded-thread-permissions-types.js';
+import type { MinimallyEncodedRawThreadInfo } from 'lib/types/minimally-encoded-thread-permissions-types.js';
 import type {
   ReportStore,
   ClientReportCreationRequest,
@@ -75,7 +76,6 @@
 import type {
   ClientDBThreadInfo,
   LegacyRawThreadInfo,
-  RawThreadInfo,
   RawThreadInfos,
 } from 'lib/types/thread-types.js';
 import {
@@ -383,7 +383,9 @@
       return state;
     }
 
-    const threadInfos: { [string]: RawThreadInfo } = {};
+    const threadInfos: {
+      [string]: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo,
+    } = {};
     const stack = [...rootIDs];
     while (stack.length > 0) {
       const threadID = stack.shift();
@@ -995,7 +997,12 @@
       threadStoreInfos: RawThreadInfos,
     ): RawThreadInfos =>
       Object.keys(threadStoreInfos).reduce(
-        (acc: { [string]: RawThreadInfo }, key: string) => {
+        (
+          acc: {
+            [string]: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo,
+          },
+          key: string,
+        ) => {
           const threadInfo = threadStoreInfos[key];
           acc[threadInfo.id] = threadInfo.minimallyEncoded
             ? threadInfo
diff --git a/web/avatars/edit-thread-avatar-menu.react.js b/web/avatars/edit-thread-avatar-menu.react.js
--- a/web/avatars/edit-thread-avatar-menu.react.js
+++ b/web/avatars/edit-thread-avatar-menu.react.js
@@ -6,7 +6,11 @@
 import { EditThreadAvatarContext } from 'lib/components/base-edit-thread-avatar-provider.react.js';
 import { useModalContext } from 'lib/components/modal-provider.react.js';
 import SWMansionIcon from 'lib/components/SWMansionIcon.react.js';
-import type { RawThreadInfo, ThreadInfo } from 'lib/types/thread-types.js';
+import type { MinimallyEncodedRawThreadInfo } from 'lib/types/minimally-encoded-thread-permissions-types.js';
+import type {
+  LegacyRawThreadInfo,
+  ThreadInfo,
+} from 'lib/types/thread-types.js';
 
 import { useUploadAvatarMedia } from './avatar-hooks.react.js';
 import css from './edit-avatar-menu.css';
@@ -22,7 +26,7 @@
 );
 
 type Props = {
-  +threadInfo: RawThreadInfo | ThreadInfo,
+  +threadInfo: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo | ThreadInfo,
 };
 function EditThreadAvatarMenu(props: Props): React.Node {
   const { threadInfo } = props;
diff --git a/web/avatars/edit-thread-avatar.react.js b/web/avatars/edit-thread-avatar.react.js
--- a/web/avatars/edit-thread-avatar.react.js
+++ b/web/avatars/edit-thread-avatar.react.js
@@ -5,15 +5,19 @@
 
 import { EditThreadAvatarContext } from 'lib/components/base-edit-thread-avatar-provider.react.js';
 import { threadHasPermission } from 'lib/shared/thread-utils.js';
+import type { MinimallyEncodedRawThreadInfo } from 'lib/types/minimally-encoded-thread-permissions-types.js';
 import { threadPermissions } from 'lib/types/thread-permission-types.js';
-import type { RawThreadInfo, ThreadInfo } from 'lib/types/thread-types.js';
+import type {
+  LegacyRawThreadInfo,
+  ThreadInfo,
+} from 'lib/types/thread-types.js';
 
 import EditThreadAvatarMenu from './edit-thread-avatar-menu.react.js';
 import css from './edit-thread-avatar.css';
 import ThreadAvatar from './thread-avatar.react.js';
 
 type Props = {
-  +threadInfo: RawThreadInfo | ThreadInfo,
+  +threadInfo: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo | ThreadInfo,
   +disabled?: boolean,
 };
 function EditThreadAvatar(props: Props): React.Node {
diff --git a/web/avatars/thread-avatar.react.js b/web/avatars/thread-avatar.react.js
--- a/web/avatars/thread-avatar.react.js
+++ b/web/avatars/thread-avatar.react.js
@@ -8,14 +8,18 @@
 } from 'lib/shared/avatar-utils.js';
 import { getSingleOtherUser } from 'lib/shared/thread-utils.js';
 import type { AvatarSize } from 'lib/types/avatar-types.js';
+import type { MinimallyEncodedRawThreadInfo } from 'lib/types/minimally-encoded-thread-permissions-types.js';
 import { threadTypes } from 'lib/types/thread-types-enum.js';
-import type { RawThreadInfo, ThreadInfo } from 'lib/types/thread-types.js';
+import type {
+  LegacyRawThreadInfo,
+  ThreadInfo,
+} from 'lib/types/thread-types.js';
 
 import Avatar from './avatar.react.js';
 import { useSelector } from '../redux/redux-utils.js';
 
 type Props = {
-  +threadInfo: RawThreadInfo | ThreadInfo,
+  +threadInfo: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo | ThreadInfo,
   +size: AvatarSize,
   +showSpinner?: boolean,
 };
diff --git a/web/avatars/thread-emoji-avatar-selection-modal.react.js b/web/avatars/thread-emoji-avatar-selection-modal.react.js
--- a/web/avatars/thread-emoji-avatar-selection-modal.react.js
+++ b/web/avatars/thread-emoji-avatar-selection-modal.react.js
@@ -12,12 +12,16 @@
   ClientAvatar,
   ClientEmojiAvatar,
 } from 'lib/types/avatar-types.js';
-import type { RawThreadInfo, ThreadInfo } from 'lib/types/thread-types.js';
+import type { MinimallyEncodedRawThreadInfo } from 'lib/types/minimally-encoded-thread-permissions-types.js';
+import type {
+  LegacyRawThreadInfo,
+  ThreadInfo,
+} from 'lib/types/thread-types.js';
 
 import EmojiAvatarSelectionModal from './emoji-avatar-selection-modal.react.js';
 
 type Props = {
-  +threadInfo: RawThreadInfo | ThreadInfo,
+  +threadInfo: LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo | ThreadInfo,
 };
 
 function ThreadEmojiAvatarSelectionModal(props: Props): React.Node {
diff --git a/web/redux/initial-state-gate.js b/web/redux/initial-state-gate.js
--- a/web/redux/initial-state-gate.js
+++ b/web/redux/initial-state-gate.js
@@ -8,7 +8,8 @@
 import type { ThreadStoreOperation } from 'lib/ops/thread-store-ops.js';
 import { allUpdatesCurrentAsOfSelector } from 'lib/selectors/keyserver-selectors.js';
 import { canUseDatabaseOnWeb } from 'lib/shared/web-database.js';
-import type { RawThreadInfo } from 'lib/types/thread-types.js';
+import type { MinimallyEncodedRawThreadInfo } from 'lib/types/minimally-encoded-thread-permissions-types.js';
+import type { LegacyRawThreadInfo } from 'lib/types/thread-types.js';
 import { convertIDToNewSchema } from 'lib/utils/migration-utils.js';
 import { entries } from 'lib/utils/objects.js';
 import { useDispatch } from 'lib/utils/redux-utils.js';
@@ -97,13 +98,18 @@
 
             const threadStoreOperations: ThreadStoreOperation[] = entries(
               threadInfos,
-            ).map(([id, threadInfo]: [string, RawThreadInfo]) => ({
-              type: 'replace',
-              payload: {
-                id,
-                threadInfo,
-              },
-            }));
+            ).map(
+              ([id, threadInfo]: [
+                string,
+                LegacyRawThreadInfo | MinimallyEncodedRawThreadInfo,
+              ]) => ({
+                type: 'replace',
+                payload: {
+                  id,
+                  threadInfo,
+                },
+              }),
+            );
 
             await processDBStoreOperations(
               {