loco-rs/loco · error
Could not delete sqlite test db
Error message
Could not delete sqlite test db
What it means
cleanup_db removes the temporary sqlite test database folder with std::fs::remove_dir_all and .expect()s on the result. If the directory cannot be deleted (files locked by an open connection, missing permissions, or the folder already removed), the expect panics with 'Could not delete sqlite test db'. This runs during test teardown, so the panic surfaces after the test body itself.
Solutions
- Ensure all DB connections are dropped/closed before cleanup_db runs (scope the pool/connection, or call explicit close).
- Run DB-backed tests with #[serial] (or a test mutex) so cleanup never races an open connection.
- Check permissions/ownership of the temp folder and the running user (CI: run with adequate tmp dir rights).
- Delete stale db_still_folder manually and rerun; add a tolerant teardown (match on the remove result) if a leftover dir is acceptable.
- On Windows, close sqlite connections or configure sqlite temp_store/journal settings to avoid lingering file handles.
Example fix
// before
fn cleanup_db(&self) {
std::fs::remove_dir_all(&self.db_folder).expect("Could not delete sqlite test db");
}
// after
fn cleanup_db(&self) {
if let Err(e) = std::fs::remove_dir_all(&self.db_folder) {
eprintln!("warning: failed to remove test db dir {:?}: {e}", self.db_folder);
}
} Defensive patterns
Strategy: try-catch
Validate before calling
// before teardown assert!(std::path::Path::new(&self.db_folder).exists(), "test db dir missing"); // ensure connections are closed: drop(pool) and let scope end before cleanup
Try / catch
match std::fs::remove_dir_all(&db_folder) {
Ok(()) => {}
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {}
Err(e) => eprintln!("cleanup warning: {e}"),
} Prevention
- Annotate DB tests with #[serial] so cleanup never overlaps open connections
- Drop/close pools and connections before teardown
- Use per-test unique temp dirs to avoid cross-test deletion races
- On Windows, be aware sqlite file locks persist until all handles close
When it happens
Trigger: Calling the sqlite TestHost's cleanup_db() when db_still_folder is still held open by an sqlite connection (Windows file locking is notorious), when the process lacks write permission on the parent directory, or when the folder was already deleted by another test/parallel run.
Common situations: Running #[serial]-less sqlite tests in parallel so one test's connection still holds the db file while another cleans up; CI containers running as non-root with restrictive temp-dir permissions; killing a previous test run that left a stale lock; Windows developers hitting OS-level file-in-use locks.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- fs service should build with success
- db connection should success
- create DB schema
- create cleanup runtime
- Drop database
AI-assisted analysis of loco-rs/loco@23639d1e36 (2026-09-12).
Data as JSON: /api/errors/d88f42090a83900a.
Report an issue: GitHub.
Appendix: source
Thrown at src/testing/db.rs:203
db_name,
&tree.root.join("test.sqlite").display().to_string(),
),
db_folder: tree.root.clone(),
_tree: tree,
})
}
}
impl TestSupport for SqliteTest {
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 {})
}
fn cleanup_db(&self) {
std::fs::remove_dir_all(&self.db_folder).expect("Could not delete sqlite test db");
}
}
pub struct Any {
connection_string: String,
}
impl Any {
#[must_use]
pub fn new(conn_str: &str) -> Self {
Self {
connection_string: conn_str.to_string(),
}
}
}
impl TestSupport for Any {
fn get_connection_str(&self) -> &str {
&self.connection_stringView on GitHub (pinned to 23639d1e36)