{"record":{"id":"50c04cd08054faf8","repo":"block/buzz","slug":"count-gate-off","errorCode":null,"errorMessage":"count, gate off","messagePattern":"count, gate off","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/buzz-db/src/runtime/tests.rs","lineNumber":1627,"sourceCode":"\n    let mut db = Db::from_pools(writer.clone(), replica.clone());\n    db.fence().force_open_for_tests(chrono::Utc::now());\n    let cid = CommunityId::from_uuid(community);\n\n    // Covered-eligible shape on purpose: pinned + until. A count must\n    // ignore that eligibility.\n    let q = {\n        let mut q = EventQuery::for_community(cid);\n        q.channel_id = Some(channel);\n        q.until = chrono::DateTime::from_timestamp((base + 60) as i64, 0);\n        q\n    };\n\n    // Budget unset ⇒ bounded arm disabled ⇒ writer.\n    let n = db\n        .count_events_routed(\"test_count\", &q)\n        .await\n        .expect(\"count, gate off\");\n    assert_eq!(n, 2, \"budget unset must count on the writer\");\n\n    // Budget set + fresh entry ⇒ bounded arm ⇒ replica.\n    db.set_replica_read_max_age_for_tests(Some(std::time::Duration::from_secs(5)));\n    let n = db\n        .count_events_routed(\"test_count\", &q)\n        .await\n        .expect(\"count, gate on\");\n    assert_eq!(n, 1, \"budget set must count on the replica (bounded)\");\n\n    // Entry older than the budget ⇒ bounded fails ⇒ writer. Covered\n    // would still hold here (upper <= wall) — proving count never\n    // consults it.\n    db.fence().close();\n    db.fence().force_open_for_tests_at(\n        chrono::Utc::now(),\n        std::time::Instant::now() - std::time::Duration::from_secs(10),\n    );","sourceCodeStart":1609,"sourceCodeEnd":1645,"githubUrl":"https://github.com/block/buzz/blob/dad5a33865fc81a2e55b3b60746632f615ec1e3a/crates/buzz-db/src/runtime/tests.rs#L1609-L1645","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nlet n = db.count_events_routed(\"test_count\", &q).await.expect(\"count, gate off\");\n// after\nlet n = db.count_events_routed(\"test_count\", &q).await\n    .unwrap_or_else(|e| panic!(\"count (gate off / writer) failed: {e}\"));","handlingStrategy":"validation","validationCode":"// Verify the writer is ready and seeded before counting\nsqlx::query(\"SELECT 1 FROM communities LIMIT 1\").execute(&writer).await\n    .expect(\"writer schema missing — run migrations\");","typeGuard":"fn writer_reachable(pool: &sqlx::PgPool) -> bool { pool.size() > 0 }","tryCatchPattern":"let n = match db.count_events_routed(\"test_count\", &q).await {\n    Ok(n) => n,\n    Err(e) => panic!(\"writer count failed: {e}\"),\n};","preventionTips":["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"],"tags":["postgres","database","test-panic","writer-pool"],"backgroundTag":"postgres-query-failed","analyzedSha":"dad5a33865fc81a2e55b3b60746632f615ec1e3a","analyzedAt":"2026-08-30T13:49:18.474Z","contentChangedAt":"2026-08-30T13:49:18.474Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}