block/buzz · error

migrated roster fence must verify

Error message

migrated roster fence must verify

What it means

Panic from `.expect("migrated roster fence must verify")` when `verify_channel_roster_fence()` returns Err on a freshly migrated scratch DB. It means the migrated schema's roster fence (trigger/function) does not satisfy the catalog verification — the migration produced a schema the verifier rejects.

Source

Thrown at crates/buzz-db/src/store/channel_members.rs:3059

                .contains("stale probe roster was accepted"),
            "behavior probe must identify inert semantics: {error}"
        );

        drop_scratch_db(&admin, pool, &scratch_name).await;
    }

    #[tokio::test]
    #[ignore = "requires Postgres"]
    async fn channel_roster_fence_catalog_verification_fails_closed() {
        let admin = PgPool::connect(&admin_url().await)
            .await
            .expect("connect admin");
        let (pool, scratch_name) = create_scratch_db(&admin, "roster_fence_catalog").await;
        let db = Db::from_pool(pool.clone());

        db.verify_channel_roster_fence()
            .await
            .expect("migrated roster fence must verify");

        let child: String = sqlx::query_scalar(
            "SELECT n.nspname || '.' || c.relname \
             FROM pg_inherits i JOIN pg_class c ON c.oid = i.inhrelid \
             JOIN pg_namespace n ON n.oid = c.relnamespace \
             WHERE i.inhparent = 'public.events'::regclass ORDER BY i.inhrelid LIMIT 1",
        )
        .fetch_one(&pool)
        .await
        .expect("load event partition");
        sqlx::query(sqlx::AssertSqlSafe(format!(
            "ALTER TABLE {child} DISABLE TRIGGER trg_events_guard_channel_roster_snapshot"
        )))
        .execute(&pool)
        .await
        .expect("disable partition roster trigger");
        let error = db
            .verify_channel_roster_fence()

View on GitHub (pinned to dad5a33865)

Solutions

  1. Re-run migrations on a fresh scratch DB to rule out partial application
  2. Compare the guard trigger/function definitions between schema.sql/migrations and what verify_channel_roster_fence expects
  3. Update whichever side drifted (migration or verifier) so a migrated DB verifies
  4. Check that the verifier accounts for partitioned-table trigger inheritance on public.events

Example fix

// before
.await.expect("migrated roster fence must verify");
// after
.await.unwrap_or_else(|e| panic!("migrated roster fence must verify: {e}"));
Defensive patterns

Strategy: try-catch

Validate before calling

// before verifying, confirm the fence objects exist
let n: i64 = sqlx::query_scalar(
    "SELECT count(*) FROM pg_trigger WHERE tgname = 'trg_events_guard_channel_roster_snapshot'"
).fetch_one(&pool).await?;
assert!(n > 0, "guard trigger missing after migration");

Try / catch

db.verify_channel_roster_fence().await
    .unwrap_or_else(|e| panic!("migrated roster fence must verify: {e}"));

Prevention

When it happens

Trigger: Scratch DB created from admin, migrations applied, but verify_channel_roster_fence finds the guard function/trigger missing, wrongly defined, or attached to the wrong tables (e.g. defined only on parent `events`, not partitions, or vice versa).

Common situations: A new migration altered or dropped trg_events_guard_channel_roster_snapshot; verifier expectations drifted from actual migration output; partial migration application on the scratch DB.

Related errors


AI-assisted analysis of block/buzz@dad5a33865 (2026-08-30). Data as JSON: /api/errors/5774eedc9bd7eb06. Report an issue: GitHub.