diff --git a/temba/orgs/migrations/0164_remove_viewers.py b/temba/orgs/migrations/0164_remove_viewers.py
new file mode 100644
index 0000000000..fb14da4fa6
--- /dev/null
+++ b/temba/orgs/migrations/0164_remove_viewers.py
@@ -0,0 +1,17 @@
+# Generated by Django 5.1.4 on 2025-01-08 20:51
+
+from django.db import migrations
+
+
+def remove_viewers(apps, schema_editor):
+ OrgMembership = apps.get_model("orgs", "OrgMembership")
+ num_deleted = OrgMembership.objects.filter(role_code="V").delete()[0]
+ if num_deleted:
+ print(f"Deleted {num_deleted} viewer memberships")
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [("orgs", "0163_squashed")]
+
+ operations = [migrations.RunPython(remove_viewers, migrations.RunPython.noop)]
diff --git a/temba/orgs/tests/test_migrations.py b/temba/orgs/tests/test_migrations.py
new file mode 100644
index 0000000000..4f93479d97
--- /dev/null
+++ b/temba/orgs/tests/test_migrations.py
@@ -0,0 +1,10 @@
+from temba.tests import MigrationTest
+
+
+class RemoveViewersTest(MigrationTest):
+ app = "orgs"
+ migrate_from = "0163_squashed"
+ migrate_to = "0164_remove_viewers"
+
+ def test_migration(self):
+ self.assertEqual({self.admin, self.editor, self.agent}, set(self.org.get_users()))
diff --git a/temba/orgs/views/views.py b/temba/orgs/views/views.py
index 9ea6dbc642..4c8917c128 100644
--- a/temba/orgs/views/views.py
+++ b/temba/orgs/views/views.py
@@ -430,7 +430,6 @@ def get_context_data(self, **kwargs):
user.role = membership.role
user.team = membership.team
- context["has_viewers"] = self.request.org.get_users(roles=[OrgRole.VIEWER]).exists()
context["has_teams"] = Org.FEATURE_TEAMS in self.request.org.features
admins = self.request.org.get_users(roles=[OrgRole.ADMINISTRATOR])
diff --git a/templates/orgs/user_list.html b/templates/orgs/user_list.html
index d1dc00781d..c942cf0c8d 100644
--- a/templates/orgs/user_list.html
+++ b/templates/orgs/user_list.html
@@ -7,16 +7,6 @@