loco-rs/loco · error
Drop database
Error message
Drop database
What it means
The `DROP DATABASE IF EXISTS {table_name};` statement executed during cleanup failed. Since it is IF EXISTS, 'not found' is not the issue — this fires on server-side SQL errors such as the database being in use (other connections), permission denied, or the server failing the command, panicking the cleanup thread.
Solutions
- Ensure all pools/connections to the test DB are closed before cleanup (drop the test pool, no background tasks holding connections)
- Use `DROP DATABASE ... WITH (FORCE)` (Postgres 13+) or terminate backends first: `SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = '...'`
- Grant the cleanup user ownership/CREATEDB rights on the test database
- Retry cleanup after a short delay to let connections drain
Example fix
// before
drop database if exists {table_name};
// after (requires PG14+ sqlx support)
drop database if exists {table_name} with (force); Defensive patterns
Strategy: retry
Validate before calling
// Terminate lingering backends before dropping // SELECT pg_terminate_backend(pid) FROM pg_stat_activity // WHERE datname = 'loco_test_x' AND pid <> pg_backend_pid();
Try / catch
// Retry the drop once after a short drain
// for attempt in 0..2 {
// if try_drop(&name).await.is_ok() { break; }
// tokio::time::sleep(Duration::from_millis(200)).await;
// } Prevention
- Drop pools holding the test DB before cleanup
- Use DROP DATABASE ... WITH (FORCE) on Postgres 13+
- Grant ownership of test DBs to the cleanup user
- Keep background workers from holding test DB connections at teardown
When it happens
Trigger: Other connections still attached to the test database (idle pools, background workers) causing 'database is being accessed by other users'; insufficient privilege to drop; server-side error on the drop statement.
Common situations: Postgres refusing DROP DATABASE while sessions are open in CI; a crashed test leaving a connection alive; managed Postgres where the test user lacks ownership of the DB.
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
- create DB schema
- 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/9a13fa5b252b47c0.
Report an issue: GitHub.
Appendix: source
Thrown at src/testing/db.rs:152
// 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)
.await
.expect("db connection should success");
let query = format!("drop database if exists {table_name};");
sqlx::query(AssertSqlSafe(query))
.execute(&pool)
.await
.expect("Drop database");
});
})
.join()
.expect("db cleanup thread panicked");
}
}
pub struct SqliteTest {
connection_string: String,
db_folder: PathBuf,
_tree: tree_fs::Tree, // Keep the tree alive while the test runs
}
impl SqliteTest {
/// Prepare new `SQLite` connection string.
///
/// # Errors
/// Returns an error if could not prepare the connection stringView on GitHub (pinned to 23639d1e36)