# PG::UndefinedTable: ERROR: relation "voice\_rooms" does not exist

**URL:** https://meta.discourse.org/t/pg-error-relation-voice-rooms-does-not-exist/411555
**Category:** Self-hosting
**Created:** [September 3, 2026, 9:03am UTC](https://meta.discourse.org/t/pg-error-relation-voice-rooms-does-not-exist/411555 "2026-09-03T09:03:31Z")
**Posts on this page:** 1
**Showing post:** 8

<div class="post-metadata">

### Author: ![nat](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/nat/32/235063_2.png) [@nat](https://meta.discourse.org/u/nat)
#### Post date: [September 3, 2026, 11:21am UTC](https://meta.discourse.org/t/pg-error-relation-voice-rooms-does-not-exist/411555/8 "2026-09-03T11:21:06Z")

</div>

Ok - it is probably a resenha migration that was assumed to have run but wasn’t. Since the same migration version number is used in core for voice, suddenly trying to add a column for `voice_rooms` won’t work because the table name is still `resenha_rooms`.

You can run this for now in your psql:

```sql
DO
$$
  DECLARE
    has_resenha boolean;
    has_voice boolean;
    table_pair record;
  BEGIN
    SELECT EXISTS (SELECT 1
                   FROM unnest(ARRAY [
                     'resenha_rooms',
                     'resenha_room_memberships',
                     'resenha_sessions',
                     'resenha_co_presences',
                     'resenha_recordings',
                     'resenha_invites'
                     ]) AS names(name)
                   WHERE to_regclass(format('public.%I', name)) IS NOT NULL)
    INTO has_resenha;

    SELECT EXISTS (SELECT 1
                   FROM unnest(ARRAY [
                     'voice_rooms',
                     'voice_room_memberships',
                     'voice_sessions',
                     'voice_co_presences',
                     'voice_recordings',
                     'voice_invites'
                     ]) AS names(name)
                   WHERE to_regclass(format('public.%I', name)) IS NOT NULL)
    INTO has_voice;

    IF has_resenha AND has_voice THEN
      RAISE EXCEPTION
        'Both Resenha and Voice tables exist. Nothing was changed.';
    END IF;

    IF NOT has_resenha THEN
      IF to_regclass('public.voice_rooms') IS NOT NULL THEN
        RAISE NOTICE 'The tables have already been renamed.';
        RETURN;
      END IF;

      RAISE EXCEPTION
        'Neither resenha_rooms nor voice_rooms exists. Nothing was changed.';
    END IF;

    IF EXISTS (SELECT 1
               FROM schema_migrations
               WHERE version = '20260831162602') THEN
      RAISE EXCEPTION
        'The rename migration is already recorded. Nothing was changed.';
    END IF;

    FOR table_pair IN
      SELECT *
      FROM (VALUES ('resenha_rooms', 'voice_rooms', '20241107000000'),
                   ('resenha_room_memberships', 'voice_room_memberships',
                    '20241107000000'),
                   ('resenha_sessions', 'voice_sessions', '20260305165400'),
                   ('resenha_co_presences', 'voice_co_presences',
                    '20260305165401'),
                   ('resenha_recordings', 'voice_recordings', '20260717172530'),
                   ('resenha_invites', 'voice_invites',
                    '20260813160047')) AS pairs(old_name, new_name, migration_version)
      LOOP
        IF EXISTS (SELECT 1
                   FROM schema_migrations
                   WHERE version = table_pair.migration_version) AND
           to_regclass(format('public.%I', table_pair.old_name)) IS NULL THEN
          RAISE EXCEPTION
            'Migration % is recorded, but table % is missing. Nothing was changed.',
            table_pair.migration_version,
            table_pair.old_name;
        END IF;

        IF to_regclass(format('public.%I', table_pair.old_name)) IS NOT NULL THEN
          EXECUTE format(
            'ALTER TABLE public.%I RENAME TO %I',
            table_pair.old_name,
            table_pair.new_name
                  );

          RAISE NOTICE 'Renamed % to %', table_pair.old_name, table_pair.new_name;
        END IF;
      END LOOP;
  END
$$;

```

It does the following:

1. checks which Resenha and Voice tables exist.
2. will refuse to continue if both exist (I am not expecting this to happen)
3. checks that the recorded migrations are what we expect
4. renames existing tables:
  - resenha\_rooms → voice\_rooms
  - resenha\_room\_memberships → voice\_room\_memberships
  - resenha\_sessions → voice\_sessions
  - resenha\_co\_presences → voice\_co\_presences
  - resenha\_recordings → voice\_recordings
  - resenha\_invites → voice\_invites

5. this helps with the weird middle state you have. rebuild after should succeed

It should allow the rest of your core migrations to succeed (will no-op the most recent core voice migration which does the rename).

I’ll check with our team if we should commit this as a rake task.

---

_[View the full topic](https://meta.discourse.org/t/pg-error-relation-voice-rooms-does-not-exist/411555)._
