block/buzz · error

seed replica member

Error message

seed replica member

What it means

This is `.expect("seed replica member")` on `relay_members::add_relay_member(&replica, cid, &replica_only, "member", None)`. It seeds a different pubkey (`bb`…`bb`) into the replica so divergent rows can prove which pool served later reads. It panics if the replica insert fails — FK violation on the community row, missing `relay_members` table in the replica scratch DB, or connection failure.

Source

Thrown at crates/buzz-db/src/runtime/tests.rs:1689

    let community = Uuid::new_v4();
    for pool in [&writer, &replica] {
        sqlx::query("INSERT INTO communities (id, host) VALUES ($1, $2)")
            .bind(community)
            .bind(format!("member-routing-{}.example", community.simple()))
            .execute(pool)
            .await
            .expect("insert community");
    }
    let cid = CommunityId::from_uuid(community);
    let writer_only = "aa".repeat(32);
    let replica_only = "bb".repeat(32);
    relay_members::add_relay_member(&writer, cid, &writer_only, "member", None)
        .await
        .expect("seed writer member");
    relay_members::add_relay_member(&replica, cid, &replica_only, "member", None)
        .await
        .expect("seed replica member");

    let mut db = Db::from_pools(writer.clone(), replica.clone());
    db.fence().force_open_for_tests(chrono::Utc::now());

    // Budget unset ⇒ bounded arm disabled ⇒ writer.
    assert!(
        db.is_relay_member(cid, &writer_only)
            .await
            .expect("gate off"),
        "budget unset must answer from the writer"
    );
    assert!(!db.is_relay_member(cid, &replica_only).await.unwrap());

    // Budget set + fresh entry ⇒ replica.
    db.set_replica_read_max_age_for_tests(Some(std::time::Duration::from_secs(5)));
    assert!(
        db.is_relay_member(cid, &replica_only)
            .await

View on GitHub (pinned to dad5a33865)

Solutions

  1. Apply migrations to the replica scratch DB before seeding.
  2. Verify the `communities` INSERT ran on the replica (the loop covers both pools — confirm no early exit).
  3. Surface the inner sqlx error for diagnosis instead of a bare label.
  4. Ensure the replica scratch DB accepts writes — it's a standalone scratch DB, not a physical standby.
  5. Re-run with fresh `mem_r` scratch DB to rule out leftover conflicting rows.

Example fix

// before
relay_members::add_relay_member(&replica, cid, &replica_only, "member", None)
    .await.expect("seed replica member");
// after
relay_members::add_relay_member(&replica, cid, &replica_only, "member", None)
    .await.unwrap_or_else(|e| panic!("seed replica member failed: {e}"));
Defensive patterns

Strategy: validation

Validate before calling

// Confirm the replica scratch DB is writable and migrated before seeding
let ok: bool = sqlx::query_scalar(
    "SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name='relay_members')")
    .fetch_one(&replica).await.unwrap_or(false);
assert!(ok, "replica scratch DB missing relay_members — run migrations");

Type guard

async fn is_writable(pool: &sqlx::PgPool) -> bool {
    sqlx::query("SELECT 1").execute(pool).await.is_ok()
}

Try / catch

relay_members::add_relay_member(&replica, cid, &replica_only, "member", None)
    .await.unwrap_or_else(|e| panic!("seed replica member failed: {e}"));

Prevention

When it happens

Trigger: Calling `add_relay_member` on the replica scratch pool when the replica DB was never migrated, its `communities` row wasn't inserted, or the replica pool connection has dropped.

Common situations: Scratch DBs created without schema; the seeded community id differing between pools due to a harness bug; write attempts against a read-only/standby replica configured in a real deployment scenario; column-type mismatch after schema evolution.

Related errors


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