block/buzz · error

connect desired-schema scratch db

Error message

connect desired-schema scratch db

What it means

After creating the scratch database, the test opens a single-connection pool to it. The expect panics when connecting to the freshly created scratch_url fails — most often because Postgres is still finishing CREATE DATABASE bookkeeping, the scratch name in the URL is wrong (see the rfind split), or the createdb was rolled back.

Source

Thrown at crates/buzz-db/src/store/channel_members.rs:3141

        let admin = PgPool::connect(&admin_url().await)
            .await
            .expect("connect admin");
        let scratch_name = format!("schema_roster_role_{}", Uuid::new_v4().simple());
        sqlx::query(sqlx::AssertSqlSafe(format!(
            "CREATE DATABASE {scratch_name}"
        )))
        .execute(&admin)
        .await
        .expect("create desired-schema scratch db");
        let base_url = admin_url().await;
        let slash = base_url.rfind('/').expect("database URL has path segment");
        let scratch_url = format!("{}/{}", &base_url[..slash], scratch_name);
        let pool = PgPoolOptions::new()
            .max_connections(1)
            .connect(&scratch_url)
            .await
            .expect("connect desired-schema scratch db");
        sqlx::raw_sql(include_str!("../../../../schema/schema.sql"))
            .execute(&pool)
            .await
            .expect("apply desired-state schema");

        let db = Db::from_pool(pool.clone());
        let community_uuid = Uuid::new_v4();
        let community = CommunityId::from_uuid(community_uuid);
        let channel = Uuid::new_v4();
        let relay_keys = Keys::generate();
        let owner_keys = Keys::generate();
        let owner = owner_keys.public_key().to_bytes();
        seed_community_channel(&pool, community_uuid, channel, &owner_keys).await;
        let member = Keys::generate().public_key().to_bytes();
        sqlx::query(
            "INSERT INTO channel_members (community_id, channel_id, pubkey, role, invited_by) \
             VALUES ($1, $2, $3, 'admin', $4)",
        )

View on GitHub (pinned to dad5a33865)

Solutions

  1. Fix the URL construction to use Url::set_path so the scratch name is placed correctly
  2. Verify the database exists: psql '<admin_url>' -c '\l' | grep <scratch_name>
  3. Check the scratch_url string right before connect — it must be {base}/postgres replaced with {base}/{scratch_name}
  4. Wait/retry briefly if connecting immediately after CREATE DATABASE in a race-prone environment

Example fix

// before
let scratch_url = format!("{}/{}", &base_url[..slash], scratch_name);
let pool = PgPoolOptions::new().max_connections(1).connect(&scratch_url).await.expect("connect desired-schema scratch db");
// after
assert!(!scratch_url.ends_with('/'), "scratch URL has empty database name: {scratch_url}");
let pool = PgPoolOptions::new().max_connections(1).connect(&scratch_url).await
    .expect("connect desired-schema scratch db");
Defensive patterns

Strategy: validation

Validate before calling

assert!(!scratch_url.ends_with('/'), "scratch URL has empty db name: {scratch_url}");
let exists: bool = sqlx::query_scalar(&format!("SELECT EXISTS (SELECT 1 FROM pg_database WHERE datname = '{scratch_name}')")).fetch_one(&admin).await?;

Type guard

fn scratch_url_well_formed(u: &str, name: &str) -> bool {
    url::Url::parse(u).map(|p| p.path() == format!("/{name}")).unwrap_or(false)
}

Try / catch

let pool = PgPoolOptions::new().max_connections(1).connect(&scratch_url).await
    .unwrap_or_else(|e| panic!("connect scratch db '{scratch_url}' failed: {e}"));

Prevention

When it happens

Trigger: PgPoolOptions::connect(&scratch_url) fails when the scratch URL is malformed by the string split, the database was dropped between creation and connect, or credentials valid on the admin DB lack CONNECT on the new database (default is PUBLIC CONNECT, so this usually means bad password/host).

Common situations: URL path-splitting bug producing postgres://host/ (empty db); firewall/pg_hba rules; password auth failing on the new db; hitting a pooler (pgbouncer) that does not know the new database yet.

Understand the failure class

Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.

Related errors


AI-assisted analysis of block/buzz@dad5a33865 (2026-08-30). Data as JSON: /api/errors/4405e4ca4310685e. Report an issue: GitHub.