block/buzz · error

disable partition roster trigger

Error message

disable partition roster trigger

What it means

This test disables the trg_events_guard_channel_roster_snapshot trigger on a child partition so it can assert that verify_channel_roster_fence() fails closed when the guard is missing. The panic fires when the ALTER TABLE ... DISABLE TRIGGER statement itself fails, meaning the guard could not be manipulated as the test requires, so the fail-closed assertion can never run meaningfully.

Source

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

        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()
            .await
            .expect_err("disabled partition roster fence must fail closed");
        assert!(
            error.to_string().contains(&child),
            "verification must identify the unfenced partition: {error}"
        );

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

    #[tokio::test]
    #[ignore = "requires Postgres"]
    async fn channel_roster_fence_verification_supports_size_one_pool() {
        let admin = PgPool::connect(&admin_url().await)
            .await
            .expect("connect admin");

View on GitHub (pinned to dad5a33865)

Solutions

  1. Run against a database created from the current schema/schema.sql so the partition and trigger exist
  2. Connect as the table owner or superuser (the admin URL role) before running the test
  3. Verify the child partition name still matches after migrations; update the test if trigger/partition names changed
  4. Ensure the test is only run when Postgres is up and the admin_url points at the right instance

Example fix

// before
sqlx::query(sqlx::AssertSqlSafe(format!("ALTER TABLE {child} DISABLE TRIGGER trg_events_guard_channel_roster_snapshot")))
    .execute(&pool).await.expect("disable partition roster trigger");
// after
sqlx::query(sqlx::AssertSqlSafe(format!("ALTER TABLE IF EXISTS {child} DISABLE TRIGGER IF EXISTS trg_events_guard_channel_roster_snapshot")))
    .execute(&pool).await.expect("disable partition roster trigger: is {child} a partition owned by the admin role?");
Defensive patterns

Strategy: validation

Validate before calling

let exists: bool = sqlx::query_scalar("SELECT EXISTS (SELECT 1 FROM pg_class WHERE relname = $1 AND relkind = 'r')", child).fetch_one(&pool).await?;
if !exists { panic!("partition {child} missing; cannot run roster fence test"); }

Type guard

async fn partition_exists(pool: &PgPool, name: &str) -> bool {
    sqlx::query_scalar::<_, bool>("SELECT EXISTS (SELECT 1 FROM pg_class WHERE relname = $1 AND relkind = 'r')")
        .bind(name).fetch_one(pool).await.unwrap_or(false)
}

Prevention

When it happens

Trigger: Running the #[ignore]d Postgres test that calls ALTER TABLE {child} DISABLE TRIGGER on a child partition that does not exist, is not a table (e.g. it is a view/foreign table), or where the connected role lacks ownership privileges on the partition.

Common situations: Schema drift between schema/schema.sql and the partition names the test hardcodes; running as a non-superuser/non-owner role that cannot ALTER TABLE; migrations renamed or dropped the trigger; connecting to the wrong database that has no partitions.

Related errors


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