loco-rs/loco · error
create DB schema
Error message
create DB schema
What it means
After connecting as root, `init_db` issues `CREATE DATABASE {schema_name};`. If that SQL fails — the database already exists, insufficient privileges, invalid identifier, or the server rejects concurrent creation — `.expect("create DB schema")` panics inside the test-support initializer.
Solutions
- Re-run with a clean DB state or drop leftovers: `psql -U postgres -c 'DROP DATABASE IF EXISTS loco_test_x;'`
- Ensure each test process/worker uses a unique schema name (unique suffix per PID) to avoid parallel collisions
- Grant the test root CREATEDB: `ALTER USER test_user CREATEDB;` or run tests against a local superuser Postgres
- Use `createdb`-capable local Postgres in CI rather than managed instances with restricted privileges
Example fix
// before $ cargo test # panics: database "loco_test_abc" already exists // after $ psql -U postgres -c 'DROP DATABASE IF EXISTS loco_test_abc;' $ cargo test
Defensive patterns
Strategy: validation
Validate before calling
// Ensure the user can create databases and no leftover DB exists // psql -U postgres -c "SELECT rolcreatedb FROM pg_roles WHERE rolname='test_user';" // psql -U postgres -c "DROP DATABASE IF EXISTS loco_test_tmp;"
Prevention
- Use unique per-process schema names to avoid parallel-test collisions
- Drop leftover test databases before reruns
- Grant CREATEDB to the test user
- Avoid managed Postgres without CREATE DATABASE rights for integration tests
When it happens
Trigger: Running tests with parallel test binaries that pick the same schema name (database already exists), a root user lacking CREATEDB, or a schema name with characters requiring quoting.
Common situations: Two test crates sharing the same `--test-threads` DB name in one CI job; leftover DB from a previous crashed run; managed Postgres (e.g. RDS/Cloud SQL) where the test user is not a superuser and cannot CREATE DATABASE.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
- Drop database
- db connection should success
- db cleanup thread panicked
- create cleanup runtime
- Could not delete sqlite test db
AI-assisted analysis of loco-rs/loco@23639d1e36 (2026-09-12).
Data as JSON: /api/errors/38cdd8becd7a2c47.
Report an issue: GitHub.
Appendix: source
Thrown at src/testing/db.rs:127
}
}
impl TestSupport for PostgresTest {
fn get_connection_str(&self) -> &str {
&self.connection_string
}
fn init_db<'a>(&'a self) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
let pool = Pool::<Postgres>::connect(&self.root_connection_string)
.await
.expect("db connection should success");
let query = format!("CREATE DATABASE {};", self.schema_name);
sqlx::query(AssertSqlSafe(query))
.execute(&pool)
.await
.expect("create DB schema");
})
}
fn cleanup_db(&self) {
let connection_string = self.root_connection_string.clone();
let table_name = self.schema_name.clone();
// Run the drop on a dedicated OS thread with its own runtime (not
// `tokio::task::spawn_blocking`, which schedules onto the ambient
// runtime and cannot be awaited from a sync/Drop context) and `.join()`
// it so cleanup fully completes before `cleanup_db` returns. This is
// safe to call from `Drop::drop` since nothing here is `.await`ed on
// the caller's runtime.
std::thread::spawn(move || {
let rt = tokio::runtime::Runtime::new().expect("create cleanup runtime");
rt.block_on(async {
let pool = Pool::<Postgres>::connect(&connection_string)View on GitHub (pinned to 23639d1e36)