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)
.awaitView on GitHub (pinned to dad5a33865)
Solutions
- Apply migrations to the replica scratch DB before seeding.
- Verify the `communities` INSERT ran on the replica (the loop covers both pools — confirm no early exit).
- Surface the inner sqlx error for diagnosis instead of a bare label.
- Ensure the replica scratch DB accepts writes — it's a standalone scratch DB, not a physical standby.
- 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
- Migrate the replica scratch DB before seeding
- Insert the community row on the replica too (the loop must complete both pools)
- Use a standalone scratch DB, not a physical standby, for write seeding
- Clean conflicting rows from prior runs
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.