SeaQL/sea-orm · error
No connection
Error message
No connection
What it means
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.
Source
Thrown at sea-orm-sync/src/driver/rusqlite.rs:674
if self.transaction_depth > 0 {
self.rollback()?;
}
Ok(())
}
}
impl Drop for RusqliteInnerConnection {
fn drop(&mut self) {
let mut loan = self.loan.lock().unwrap();
loan.return_(self.conn.loan());
}
}
impl State {
fn conn(&self) -> &RusqliteConnection {
match self {
State::Idle(conn) => conn,
_ => panic!("No connection"),
}
}
fn loan(&mut self) -> RusqliteConnection {
let mut conn = State::Loaned;
std::mem::swap(&mut conn, self);
match conn {
State::Idle(conn) => conn,
_ => panic!("No connection"),
}
}
fn return_(&mut self, conn: RusqliteConnection) {
*self = State::Idle(conn);
}
}
impl From<OwnedRow> for QueryResult {View on GitHub (pinned to e29bcd1b41)
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
Example fix
// before
conn.query_all(q1, |row| {
conn.query_all(q2, ...)?; // panics: connection loaned
Ok(())
})?;
// after
let rows = conn.query_all(q1, to_model)?;
let details = conn.query_all(q2, to_detail)?; // sequential use Defensive patterns
Strategy: fallback
Validate before calling
// never nest queries on the same connection; collect results first:
let parents = conn.query_all(parent_q, to_model)?;
for p in &parents { let kids = conn.query_all(child_q(p.id), to_model)?; } Try / catch
let r = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| state.conn()));
if r.is_err() { /* the connection is loaned; retry after the outer operation completes */ } Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Not SQLite Connection
- Not SQLite Connection
- Fail to acquire mocker
- Should only have one owner
- Fail to rollback transaction
AI-assisted analysis of SeaQL/sea-orm@e29bcd1b41 (2026-09-10).
Data as JSON: /api/errors/447ba7d6cc0e7722.
Report an issue: GitHub.