block/buzz · error
count, gate off
Error message
count, gate off
What it means
This is `.expect("count, gate off")` on `db.count_events_routed("test_count", &q)` in `count_events_routed_is_bounded_only`. It panics if the count query fails while the replica-read budget is unset (routing gate disabled, so the count runs on the writer). The expect converts any sqlx/database error into a panic labeled with the routing arm being proven.
Source
Thrown at crates/buzz-db/src/runtime/tests.rs:1627
let mut db = Db::from_pools(writer.clone(), replica.clone());
db.fence().force_open_for_tests(chrono::Utc::now());
let cid = CommunityId::from_uuid(community);
// Covered-eligible shape on purpose: pinned + until. A count must
// ignore that eligibility.
let q = {
let mut q = EventQuery::for_community(cid);
q.channel_id = Some(channel);
q.until = chrono::DateTime::from_timestamp((base + 60) as i64, 0);
q
};
// Budget unset ⇒ bounded arm disabled ⇒ writer.
let n = db
.count_events_routed("test_count", &q)
.await
.expect("count, gate off");
assert_eq!(n, 2, "budget unset must count on the writer");
// Budget set + fresh entry ⇒ bounded arm ⇒ replica.
db.set_replica_read_max_age_for_tests(Some(std::time::Duration::from_secs(5)));
let n = db
.count_events_routed("test_count", &q)
.await
.expect("count, gate on");
assert_eq!(n, 1, "budget set must count on the replica (bounded)");
// Entry older than the budget ⇒ bounded fails ⇒ writer. Covered
// would still hold here (upper <= wall) — proving count never
// consults it.
db.fence().close();
db.fence().force_open_for_tests_at(
chrono::Utc::now(),
std::time::Instant::now() - std::time::Duration::from_secs(10),
);View on GitHub (pinned to dad5a33865)
Solutions
- Ensure Postgres is running and the writer scratch DB was created and migrated.
- Confirm `seed_community_channel` ran on the writer before counting.
- Inspect the underlying sqlx error by replacing expect with a panic that prints `{e}`.
- Re-run the test alone (`cargo test -p buzz-db count_events_routed -- --ignored`) to rule out cross-test interference on shared scratch names.
- Check the EventQuery (`for_community` + channel_id + until) matches seeded data shape.
Example fix
// before
let n = db.count_events_routed("test_count", &q).await.expect("count, gate off");
// after
let n = db.count_events_routed("test_count", &q).await
.unwrap_or_else(|e| panic!("count (gate off / writer) failed: {e}")); Defensive patterns
Strategy: validation
Validate before calling
// Verify the writer is ready and seeded before counting
sqlx::query("SELECT 1 FROM communities LIMIT 1").execute(&writer).await
.expect("writer schema missing — run migrations"); Type guard
fn writer_reachable(pool: &sqlx::PgPool) -> bool { pool.size() > 0 } Try / catch
let n = match db.count_events_routed("test_count", &q).await {
Ok(n) => n,
Err(e) => panic!("writer count failed: {e}"),
}; Prevention
- Migrate scratch DBs immediately after create_scratch_db
- Seed community/channel rows before counting
- Keep pools alive for the whole test — no early drop_scratch_db
- Print inner errors instead of bare expect labels
When it happens
Trigger: Calling `count_events_routed` on the writer pool with `set_replica_read_max_age_for_tests` never invoked, when the writer scratch DB is unreachable, missing the events schema, or the seeded rows/community/channel rows are absent causing a constraint or SQL error.
Common situations: Scratch DBs created without migrations applied; writer pool connection dropped mid-test; test run without Postgres; divergent seed helpers failing silently earlier leaving the query shape invalid.
Related errors
AI-assisted analysis of block/buzz@dad5a33865 (2026-08-30).
Data as JSON: /api/errors/50c04cd08054faf8.
Report an issue: GitHub.