block/buzz · error
count, gate on
Error message
count, gate on
What it means
This is `.expect("count, gate on")` on `count_events_routed` after `set_replica_read_max_age_for_tests(Some(5s))` enables the bounded arm, so the count must be served from the replica pool. The expect panics if the replica-served COUNT fails — typically a replica connectivity or schema problem. Its distinct label lets you tell which routing arm was active when the query failed.
Source
Thrown at crates/buzz-db/src/runtime/tests.rs:1635
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),
);
let n = db
.count_events_routed("test_count", &q)
.await
.expect("count, entry too old");
assert_eq!(
n, 2,
"an over-budget entry must fail the count closed to the writer, \
even when the covered arm would admit the shape"View on GitHub (pinned to dad5a33865)
Solutions
- Verify the replica scratch DB (`cnt_r`) still exists and has the events schema/migrations.
- Call `db.fence().force_open_for_tests(chrono::Utc::now())` before setting the budget so a fresh proved entry exists.
- Print the inner sqlx error instead of panicking with just the label to see the root cause.
- Restart Postgres and re-run; drop leftover scratch DBs from prior runs.
- Confirm `set_replica_read_max_age_for_tests(Some(Duration::from_secs(5)))` precedes this call.
Example fix
// before
let n = db.count_events_routed("test_count", &q).await.expect("count, gate on");
// after
let n = db.count_events_routed("test_count", &q).await
.unwrap_or_else(|e| panic!("count (gate on / replica bounded) failed: {e}")); Defensive patterns
Strategy: validation
Validate before calling
// Confirm replica readiness and a fresh fence entry before the bounded arm
sqlx::query("SELECT 1").execute(db.replica()).await.expect("replica unreachable");
db.fence().force_open_for_tests(chrono::Utc::now());
db.set_replica_read_max_age_for_tests(Some(std::time::Duration::from_secs(5))); Type guard
fn budget_enabled(db: &Db) -> bool { db.replica_read_max_age().is_some() } Try / catch
let n = db.count_events_routed("test_count", &q).await
.unwrap_or_else(|e| panic!("bounded count failed (replica arm): {e}")); Prevention
- Open the fence and force a fresh entry before enabling the budget
- Check the replica scratch DB exists and is migrated
- Avoid long seed phases that let pools idle-timeout
- Drop stale scratch DBs from previous runs
When it happens
Trigger: Calling `count_events_routed` on the bounded/replica arm in `count_events_routed_is_bounded_only` when the replica scratch DB is down, unmigrated, or its connection pool has been closed or timed out; also if the fenced entry is missing so routing errors instead of falling back.
Common situations: Replica scratch DB dropped by a prior failed test run; `fence().force_open_for_tests` not called before enabling the budget; stale connection after long-running seeds; Postgres restart between arms of the test.
Related errors
AI-assisted analysis of block/buzz@dad5a33865 (2026-08-30).
Data as JSON: /api/errors/7656e8c0ecd43a3f.
Report an issue: GitHub.