transact-rs/sqlx · error
cleanup_test() invoked outside `#[sqlx::test]`
Error message
cleanup_test() invoked outside `#[sqlx::test]`
What it means
Postgres's testing support `cleanup_test` acquires from `MASTER_POOL`, a global pool initialized only inside `#[sqlx::test]`. `.get()` on the uninitialized Option panics with this message when cleanup is called outside the macro's context.
Source
Thrown at sqlx-postgres/src/testing/mod.rs:34
use crate::{PgConnectOptions, PgConnection, Postgres};
pub(crate) use sqlx_core::testing::*;
// Using a blocking `OnceLock` here because the critical sections are short.
static MASTER_POOL: OnceLock<Pool<Postgres>> = OnceLock::new();
// Automatically delete any databases created before the start of the test binary.
impl TestSupport for Postgres {
fn test_context(
args: &TestArgs,
) -> impl Future<Output = Result<TestContext<Self>, Error>> + Send + '_ {
test_context(args)
}
async fn cleanup_test(db_name: &str) -> Result<(), Error> {
let mut conn = MASTER_POOL
.get()
.expect("cleanup_test() invoked outside `#[sqlx::test]`")
.acquire()
.await?;
do_cleanup(&mut conn, db_name).await
}
async fn cleanup_test_dbs() -> Result<Option<usize>, Error> {
let url = dotenvy::var("DATABASE_URL").expect("DATABASE_URL must be set");
let mut conn = PgConnection::connect(&url).await?;
let delete_db_names: Vec<String> = query_scalar("select db_name from _sqlx_test.databases")
.fetch_all(&mut conn)
.await?;
if delete_db_names.is_empty() {
return Ok(None);
}View on GitHub (pinned to 03af8bcc57)
Solutions
- Run the test under `#[sqlx::test]` so MASTER_POOL is initialized; let the macro handle cleanup.
- Delete explicit `cleanup_test` calls from non-macro tests.
- For bespoke cleanup, create your own PgPool from DATABASE_URL and run the cleanup SQL yourself.
Example fix
// before
#[tokio::test]
async fn t() { cleanup_test("mydb").await.unwrap(); }
// after
#[sqlx::test]
async fn t(pool: PgPool) { /* automatic cleanup */ } Defensive patterns
Strategy: validation
Validate before calling
// cleanup_test requires the #[sqlx::test] context; enforce by convention:
// prefer:
#[sqlx::test]
async fn my_test(pool: sqlx::PgPool) { /* ... */ }
// and delete any manual calls to cleanup_test Prevention
- Let #[sqlx::test] own pool setup and teardown
- Do not invoke testing-module helpers from non-macro tests or binaries
- Grep for `cleanup_test(` in reviews to catch out-of-context calls
When it happens
Trigger: Calling the testing API's `cleanup_test(db_name)` from a non-`#[sqlx::test]` test or ordinary async code, so MASTER_POOL was never set.
Common situations: Refactoring tests away from `#[sqlx::test]` while retaining cleanup calls; invoking cleanup in helpers, `Drop` impls, or a separate binary; ordering issues where cleanup runs before any sqlx test initialized the pool.
Related errors
- cleanup_test() invoked outside `#[sqlx::test]`
- DATABASE_URL must be set
- failed to close setup connection
- DATABASE_URL must be set
- failed to parse DATABASE_URL
AI-assisted analysis of transact-rs/sqlx@03af8bcc57 (2026-09-03).
Data as JSON: /api/errors/8b5a79c1e33e9c65.
Report an issue: GitHub.