diff --git a/lib/permissions/special-roles.js b/lib/permissions/special-roles.js
--- a/lib/permissions/special-roles.js
+++ b/lib/permissions/special-roles.js
@@ -2,6 +2,8 @@
 
 import type { TRefinement } from 'tcomb';
 
+import { roleIsAdminRole, roleIsDefaultRole } from '../shared/thread-utils.js';
+import type { RoleInfo } from '../types/minimally-encoded-thread-permissions-types.js';
 import { values } from '../utils/objects.js';
 import { tNumEnum } from '../utils/validation-utils.js';
 
@@ -19,3 +21,20 @@
   Members: specialRoles.DEFAULT_ROLE,
   Admins: specialRoles.ADMIN_ROLE,
 });
+
+function patchRoleInfoWithSpecialRole(role: RoleInfo): RoleInfo {
+  if (roleIsDefaultRole(role)) {
+    return {
+      ...role,
+      specialRole: specialRoles.DEFAULT_ROLE,
+    };
+  } else if (roleIsAdminRole(role)) {
+    return {
+      ...role,
+      specialRole: specialRoles.ADMIN_ROLE,
+    };
+  }
+  return role;
+}
+
+export { patchRoleInfoWithSpecialRole };
diff --git a/lib/permissions/special-roles.test.js b/lib/permissions/special-roles.test.js
new file mode 100644
--- /dev/null
+++ b/lib/permissions/special-roles.test.js
@@ -0,0 +1,42 @@
+// @flow
+
+import { patchRoleInfoWithSpecialRole, specialRoles } from './special-roles.js';
+import type { RoleInfo } from '../types/minimally-encoded-thread-permissions-types.js';
+
+describe('patchRoleInfoWithSpecialRole', () => {
+  it('should correctly set DEFAULT_ROLE', () => {
+    const role: RoleInfo = {
+      minimallyEncoded: true,
+      id: 'roleID',
+      name: 'roleName',
+      permissions: ['abc', 'def'],
+      isDefault: true,
+    };
+    const patchedRole = patchRoleInfoWithSpecialRole(role);
+    expect(patchedRole.specialRole).toBe(specialRoles.DEFAULT_ROLE);
+  });
+
+  it('should correctly set ADMIN_ROLE', () => {
+    const role: RoleInfo = {
+      minimallyEncoded: true,
+      id: 'roleID',
+      name: 'Admins',
+      permissions: ['abc', 'def'],
+      isDefault: false,
+    };
+    const patchedRole = patchRoleInfoWithSpecialRole(role);
+    expect(patchedRole.specialRole).toBe(specialRoles.ADMIN_ROLE);
+  });
+
+  it('should correctly set undefined', () => {
+    const role: RoleInfo = {
+      minimallyEncoded: true,
+      id: 'roleID',
+      name: 'BLAH',
+      permissions: ['abc', 'def'],
+      isDefault: false,
+    };
+    const patchedRole = patchRoleInfoWithSpecialRole(role);
+    expect(patchedRole.specialRole).toBe(undefined);
+  });
+});
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
@@ -1083,6 +1083,12 @@
   return !!memberInfo.permissions[threadPermissions.CHANGE_ROLE]?.value;
 }
 
+function roleIsDefaultRole(
+  roleInfo: ?ClientLegacyRoleInfo | ?RoleInfo,
+): boolean {
+  return !!(roleInfo && roleInfo.isDefault);
+}
+
 function roleIsAdminRole(roleInfo: ?ClientLegacyRoleInfo | ?RoleInfo): boolean {
   return !!(roleInfo && !roleInfo.isDefault && roleInfo.name === 'Admins');
 }
@@ -1845,6 +1851,7 @@
   threadInfoFromRawThreadInfo,
   threadTypeDescriptions,
   memberHasAdminPowers,
+  roleIsDefaultRole,
   roleIsAdminRole,
   threadHasAdminRole,
   identifyInvalidatedThreads,