{"record":{"id":"447ba7d6cc0e7722","repo":"SeaQL/sea-orm","slug":"no-connection","errorCode":null,"errorMessage":"No connection","messagePattern":"No connection","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sea-orm-sync/src/driver/rusqlite.rs","lineNumber":674,"sourceCode":"        if self.transaction_depth > 0 {\n            self.rollback()?;\n        }\n        Ok(())\n    }\n}\n\nimpl Drop for RusqliteInnerConnection {\n    fn drop(&mut self) {\n        let mut loan = self.loan.lock().unwrap();\n        loan.return_(self.conn.loan());\n    }\n}\n\nimpl State {\n    fn conn(&self) -> &RusqliteConnection {\n        match self {\n            State::Idle(conn) => conn,\n            _ => panic!(\"No connection\"),\n        }\n    }\n\n    fn loan(&mut self) -> RusqliteConnection {\n        let mut conn = State::Loaned;\n        std::mem::swap(&mut conn, self);\n        match conn {\n            State::Idle(conn) => conn,\n            _ => panic!(\"No connection\"),\n        }\n    }\n\n    fn return_(&mut self, conn: RusqliteConnection) {\n        *self = State::Idle(conn);\n    }\n}\n\nimpl From<OwnedRow> for QueryResult {","sourceCodeStart":656,"sourceCodeEnd":692,"githubUrl":"https://github.com/SeaQL/sea-orm/blob/e29bcd1b417c41a553b386fe94511d7c64a1c8ec/sea-orm-sync/src/driver/rusqlite.rs#L656-L692","documentation":"The rusqlite driver keeps the SQLite connection in a State enum (Idle, Loaned, etc.). conn() dereferences the connection and panics with \"No connection\" when the state is not Idle — i.e. the connection is currently loaned out (or absent), so it cannot be handed to the caller.","triggerScenarios":"Calling conn() while the connection is in the Loaned state — typically re-entrant use of the same rusqlite connection, or use after the pool state was set to a non-Idle variant without being returned.","commonSituations":"Nested query execution on the same connection (a query callback triggering another query); a loaned connection never returned due to an early-return/panic path; concurrent access to a single rusqlite connection without proper synchronization.","solutions":["Avoid re-entrant/nested use of the same connection: complete or release the current loan before requesting conn() again","Ensure every loan() is paired with a return of the connection on all paths (use a guard so panics/early returns restore Idle)","Serialize access to the connection (Mutex/synchronization) so it is never taken while loaned"],"exampleFix":"// before\nconn.query_all(q1, |row| {\n    conn.query_all(q2, ...)?; // panics: connection loaned\n    Ok(())\n})?;\n// after\nlet rows = conn.query_all(q1, to_model)?;\nlet details = conn.query_all(q2, to_detail)?; // sequential use","handlingStrategy":"fallback","validationCode":"// never nest queries on the same connection; collect results first:\nlet parents = conn.query_all(parent_q, to_model)?;\nfor p in &parents { let kids = conn.query_all(child_q(p.id), to_model)?; }","typeGuard":null,"tryCatchPattern":"let r = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| state.conn()));\nif r.is_err() { /* the connection is loaned; retry after the outer operation completes */ }","preventionTips":["Do not execute queries inside row-mapping callbacks that use the same connection","Guarantee loaned connections are returned on all paths (RAII guard, no early `?` before restore)","Wrap the rusqlite connection in a Mutex if multiple call sites can reach it concurrently"],"tags":["panic","sqlite","rusqlite","concurrency"],"backgroundTag":"invalid-state-transition","analyzedSha":"e29bcd1b417c41a553b386fe94511d7c64a1c8ec","analyzedAt":"2026-09-10T11:31:52.468Z","contentChangedAt":"2026-09-10T11:31:52.468Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}