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
@@ -223,8 +223,11 @@
   return { threadInfos };
 }
 
+export type RawThreadInfos = {
+  +[id: string]: RawThreadInfo,
+};
 export type FetchThreadInfosResult = {
-  +threadInfos: { +[id: string]: RawThreadInfo },
+  +threadInfos: RawThreadInfos,
 };
 
 async function fetchThreadInfos(
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
@@ -5,22 +5,19 @@
 import type { StateSyncSpec } from './state-sync-spec.js';
 import {
   fetchThreadInfos,
-  type FetchThreadInfosResult,
+  type RawThreadInfos,
 } from '../../fetchers/thread-fetchers.js';
 import type { Viewer } from '../../session/viewer.js';
 
-export const threadsStateSyncSpec: StateSyncSpec<FetchThreadInfosResult> =
+export const threadsStateSyncSpec: StateSyncSpec<RawThreadInfos> =
   Object.freeze({
-    fetch(
+    async fetch(
       viewer: Viewer,
       query: $ReadOnlyArray<CalendarQuery>,
       ids?: $ReadOnlySet<string>,
     ) {
-      if (ids) {
-        return fetchThreadInfos(viewer, {
-          threadIDs: ids,
-        });
-      }
-      return fetchThreadInfos(viewer);
+      const filter = ids ? { threadIDs: ids } : undefined;
+      const result = await fetchThreadInfos(viewer, filter);
+      return result.threadInfos;
     },
   });
diff --git a/keyserver/src/socket/session-utils.js b/keyserver/src/socket/session-utils.js
--- a/keyserver/src/socket/session-utils.js
+++ b/keyserver/src/socket/session-utils.js
@@ -392,7 +392,7 @@
     };
     const fetchedData = await promiseAll(promises);
     const hashesToCheck = {
-      threadInfos: hash(fetchedData.threadsResult.threadInfos),
+      threadInfos: hash(fetchedData.threadsResult),
       entryInfos: hash(fetchedData.entriesResult),
       currentUserInfo: hash(fetchedData.currentUserInfo),
       userInfos: hash(fetchedData.userInfosResult),
@@ -436,12 +436,12 @@
 
   const fetchPromises = {};
   if (fetchAllThreads) {
-    fetchPromises.threadsResult = serverStateSyncSpecs.threads.fetch(
+    fetchPromises.threadInfos = serverStateSyncSpecs.threads.fetch(
       viewer,
       query,
     );
   } else if (threadIDsToFetch.size > 0) {
-    fetchPromises.threadsResult = serverStateSyncSpecs.threads.fetch(
+    fetchPromises.threadInfos = serverStateSyncSpecs.threads.fetch(
       viewer,
       query,
       threadIDsToFetch,
@@ -483,7 +483,7 @@
     if (key === 'threadInfos') {
       // Instead of returning all threadInfos, we want to narrow down and figure
       // out which threadInfos don't match first
-      const { threadInfos } = fetchedData.threadsResult;
+      const { threadInfos } = fetchedData;
       for (const threadID in threadInfos) {
         hashesToCheck[`threadInfo|${threadID}`] = hash(threadInfos[threadID]);
       }
@@ -510,7 +510,7 @@
       stateChanges.currentUserInfo = fetchedData.currentUserInfo;
     } else if (key.startsWith('threadInfo|')) {
       const [, threadID] = key.split('|');
-      const { threadInfos } = fetchedData.threadsResult;
+      const { threadInfos } = fetchedData;
       const threadInfo = threadInfos[threadID];
       if (!threadInfo) {
         if (!stateChanges.deleteThreadIDs) {