{"record":{"id":"5774eedc9bd7eb06","repo":"block/buzz","slug":"migrated-roster-fence-must-verify","errorCode":null,"errorMessage":"migrated roster fence must verify","messagePattern":"migrated roster fence must verify","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/buzz-db/src/store/channel_members.rs","lineNumber":3059,"sourceCode":"                .contains(\"stale probe roster was accepted\"),\n            \"behavior probe must identify inert semantics: {error}\"\n        );\n\n        drop_scratch_db(&admin, pool, &scratch_name).await;\n    }\n\n    #[tokio::test]\n    #[ignore = \"requires Postgres\"]\n    async fn channel_roster_fence_catalog_verification_fails_closed() {\n        let admin = PgPool::connect(&admin_url().await)\n            .await\n            .expect(\"connect admin\");\n        let (pool, scratch_name) = create_scratch_db(&admin, \"roster_fence_catalog\").await;\n        let db = Db::from_pool(pool.clone());\n\n        db.verify_channel_roster_fence()\n            .await\n            .expect(\"migrated roster fence must verify\");\n\n        let child: String = sqlx::query_scalar(\n            \"SELECT n.nspname || '.' || c.relname \\\n             FROM pg_inherits i JOIN pg_class c ON c.oid = i.inhrelid \\\n             JOIN pg_namespace n ON n.oid = c.relnamespace \\\n             WHERE i.inhparent = 'public.events'::regclass ORDER BY i.inhrelid LIMIT 1\",\n        )\n        .fetch_one(&pool)\n        .await\n        .expect(\"load event partition\");\n        sqlx::query(sqlx::AssertSqlSafe(format!(\n            \"ALTER TABLE {child} DISABLE TRIGGER trg_events_guard_channel_roster_snapshot\"\n        )))\n        .execute(&pool)\n        .await\n        .expect(\"disable partition roster trigger\");\n        let error = db\n            .verify_channel_roster_fence()","sourceCodeStart":3041,"sourceCodeEnd":3077,"githubUrl":"https://github.com/block/buzz/blob/dad5a33865fc81a2e55b3b60746632f615ec1e3a/crates/buzz-db/src/store/channel_members.rs#L3041-L3077","documentation":"Panic from `.expect(\"migrated roster fence must verify\")` when `verify_channel_roster_fence()` returns Err on a freshly migrated scratch DB. It means the migrated schema's roster fence (trigger/function) does not satisfy the catalog verification — the migration produced a schema the verifier rejects.","triggerScenarios":"Scratch DB created from admin, migrations applied, but verify_channel_roster_fence finds the guard function/trigger missing, wrongly defined, or attached to the wrong tables (e.g. defined only on parent `events`, not partitions, or vice versa).","commonSituations":"A new migration altered or dropped trg_events_guard_channel_roster_snapshot; verifier expectations drifted from actual migration output; partial migration application on the scratch DB.","solutions":["Re-run migrations on a fresh scratch DB to rule out partial application","Compare the guard trigger/function definitions between schema.sql/migrations and what verify_channel_roster_fence expects","Update whichever side drifted (migration or verifier) so a migrated DB verifies","Check that the verifier accounts for partitioned-table trigger inheritance on public.events"],"exampleFix":"// before\n.await.expect(\"migrated roster fence must verify\");\n// after\n.await.unwrap_or_else(|e| panic!(\"migrated roster fence must verify: {e}\"));","handlingStrategy":"try-catch","validationCode":"// before verifying, confirm the fence objects exist\nlet n: i64 = sqlx::query_scalar(\n    \"SELECT count(*) FROM pg_trigger WHERE tgname = 'trg_events_guard_channel_roster_snapshot'\"\n).fetch_one(&pool).await?;\nassert!(n > 0, \"guard trigger missing after migration\");","typeGuard":null,"tryCatchPattern":"db.verify_channel_roster_fence().await\n    .unwrap_or_else(|e| panic!(\"migrated roster fence must verify: {e}\"));","preventionTips":["Re-generate scratch DBs from the latest migrations before verifying","Diff schema.sql/migrations against verifier expectations whenever either changes","Account for partitioned-table trigger placement in verification"],"tags":["postgres","migration","trigger","verification","panic"],"backgroundTag":"migration-schema-drift","analyzedSha":"dad5a33865fc81a2e55b3b60746632f615ec1e3a","analyzedAt":"2026-08-30T13:49:18.474Z","contentChangedAt":"2026-08-30T13:49:18.474Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}