{"record":{"id":"d88f42090a83900a","repo":"loco-rs/loco","slug":"could-not-delete-sqlite-test-db","errorCode":null,"errorMessage":"Could not delete sqlite test db","messagePattern":"Could not delete sqlite test db","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/testing/db.rs","lineNumber":203,"sourceCode":"                db_name,\n                &tree.root.join(\"test.sqlite\").display().to_string(),\n            ),\n            db_folder: tree.root.clone(),\n            _tree: tree,\n        })\n    }\n}\n\nimpl TestSupport for SqliteTest {\n    fn get_connection_str(&self) -> &str {\n        &self.connection_string\n    }\n    fn init_db<'a>(&'a self) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {\n        Box::pin(async move {})\n    }\n\n    fn cleanup_db(&self) {\n        std::fs::remove_dir_all(&self.db_folder).expect(\"Could not delete sqlite test db\");\n    }\n}\n\npub struct Any {\n    connection_string: String,\n}\nimpl Any {\n    #[must_use]\n    pub fn new(conn_str: &str) -> Self {\n        Self {\n            connection_string: conn_str.to_string(),\n        }\n    }\n}\n\nimpl TestSupport for Any {\n    fn get_connection_str(&self) -> &str {\n        &self.connection_string","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/loco-rs/loco/blob/23639d1e360dbc618073642b507d6f8664adbaff/src/testing/db.rs#L185-L221","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nfn cleanup_db(&self) {\n    std::fs::remove_dir_all(&self.db_folder).expect(\"Could not delete sqlite test db\");\n}\n// after\nfn cleanup_db(&self) {\n    if let Err(e) = std::fs::remove_dir_all(&self.db_folder) {\n        eprintln!(\"warning: failed to remove test db dir {:?}: {e}\", self.db_folder);\n    }\n}","handlingStrategy":"try-catch","validationCode":"// before teardown\nassert!(std::path::Path::new(&self.db_folder).exists(), \"test db dir missing\");\n// ensure connections are closed: drop(pool) and let scope end before cleanup","typeGuard":null,"tryCatchPattern":"match std::fs::remove_dir_all(&db_folder) {\n    Ok(()) => {}\n    Err(e) if e.kind() == std::io::ErrorKind::NotFound => {}\n    Err(e) => eprintln!(\"cleanup warning: {e}\"),\n}","preventionTips":["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"],"tags":["rust","testing","sqlite","filesystem"],"backgroundTag":"file-write-failed","analyzedSha":"23639d1e360dbc618073642b507d6f8664adbaff","analyzedAt":"2026-09-12T01:47:20.769Z","contentChangedAt":"2026-09-12T01:47:20.769Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}