{"record":{"id":"9e90502c66bd5053","repo":"block/buzz","slug":"create-desired-schema-scratch-db","errorCode":null,"errorMessage":"create desired-schema scratch db","messagePattern":"create desired-schema scratch db","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/buzz-db/src/store/channel_members.rs","lineNumber":3133,"sourceCode":"\n        drop_scratch_db(&admin, pool, &scratch_name).await;\n    }\n\n    #[tokio::test]\n    #[ignore = \"requires Postgres\"]\n    async fn desired_schema_rejects_stale_legacy_roster_role() {\n        use nostr::{EventBuilder, Keys, Kind, Tag, Timestamp};\n\n        let admin = PgPool::connect(&admin_url().await)\n            .await\n            .expect(\"connect admin\");\n        let scratch_name = format!(\"schema_roster_role_{}\", Uuid::new_v4().simple());\n        sqlx::query(sqlx::AssertSqlSafe(format!(\n            \"CREATE DATABASE {scratch_name}\"\n        )))\n        .execute(&admin)\n        .await\n        .expect(\"create desired-schema scratch db\");\n        let base_url = admin_url().await;\n        let slash = base_url.rfind('/').expect(\"database URL has path segment\");\n        let scratch_url = format!(\"{}/{}\", &base_url[..slash], scratch_name);\n        let pool = PgPoolOptions::new()\n            .max_connections(1)\n            .connect(&scratch_url)\n            .await\n            .expect(\"connect desired-schema scratch db\");\n        sqlx::raw_sql(include_str!(\"../../../../schema/schema.sql\"))\n            .execute(&pool)\n            .await\n            .expect(\"apply desired-state schema\");\n\n        let db = Db::from_pool(pool.clone());\n        let community_uuid = Uuid::new_v4();\n        let community = CommunityId::from_uuid(community_uuid);\n        let channel = Uuid::new_v4();\n        let relay_keys = Keys::generate();","sourceCodeStart":3115,"sourceCodeEnd":3151,"githubUrl":"https://github.com/block/buzz/blob/dad5a33865fc81a2e55b3b60746632f615ec1e3a/crates/buzz-db/src/store/channel_members.rs#L3115-L3151","documentation":"The test creates a uniquely named scratch database with CREATE DATABASE {scratch_name} on the admin pool. The expect panics when the server rejects the statement: insufficient privilege (not CREATEDB/superuser), name collision, or CREATE DATABASE cannot run inside a transaction (sqlx runs single statements so this is rarely it) or while a template DB is in use.","triggerScenarios":"Executing CREATE DATABASE when the admin role lacks CREATEDB, a database with the generated name already exists (collision, though Uuid::new_v4 makes this unlikely), or the server is in recovery/read-only mode.","commonSituations":"Using a limited application role instead of a superuser as the admin URL; managed Postgres (RDS/Cloud SQL) that forbids CREATE DATABASE on the master user; disk-full or template1 locked states.","solutions":["Grant CREATEDB to the admin role or use the postgres superuser in the admin URL","Check for the existing database: DROP DATABASE IF EXISTS {scratch_name} or pick a new name","If managed Postgres blocks CREATE DATABASE, point the test at a local Postgres that allows it","Confirm the server is writable (not in recovery / read_only=off)"],"exampleFix":"// before\nsqlx::query(sqlx::AssertSqlSafe(format!(\"CREATE DATABASE {scratch_name}\")))\n    .execute(&admin).await.expect(\"create desired-schema scratch db\");\n// after\nsqlx::query(sqlx::AssertSqlSafe(format!(\"DROP DATABASE IF EXISTS {scratch_name}\"))).execute(&admin).await.expect(\"drop stale scratch db\");\nsqlx::query(sqlx::AssertSqlSafe(format!(\"CREATE DATABASE {scratch_name}\")))\n    .execute(&admin).await.expect(\"create desired-schema scratch db: does the admin role have CREATEDB?\");","handlingStrategy":"validation","validationCode":"let createdb: bool = sqlx::query_scalar(\"SELECT rolcreatedb FROM pg_roles WHERE rolname = current_user\").fetch_one(&admin).await?;\nassert!(createdb, \"admin role lacks CREATEDB\");","typeGuard":"async fn can_create_db(pool: &PgPool) -> bool {\n    sqlx::query_scalar::<_, bool>(\"SELECT rolcreatedb FROM pg_roles WHERE rolname = current_user\")\n        .fetch_one(pool).await.unwrap_or(false)\n}","tryCatchPattern":"if let Err(e) = create_db.execute(&admin).await {\n    if e.as_database_error().map_or(false, |d| d.is_unique_violation()) { /* drop & retry */ }\n    else { panic!(\"create scratch db failed: {e} — CREATEDB granted?\"); }\n}","preventionTips":["Grant CREATEDB to the test admin role","Use local Postgres for schema tests; managed clouds often restrict CREATE DATABASE","Use UUID names (as the test does) to avoid collisions"],"tags":["postgres","sql","permissions","test-infrastructure"],"backgroundTag":"createdb-permission-denied","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"}