SeaQL/sea-orm · error
Should only have one owner
Error message
Should only have one owner
What it means
This is the sqlx counterpart of the rusqlite shim panic: in `sea_schema_shim.rs`, `map_result` calls `Arc::into_inner(err).expect("Should only have one owner")` on `DbErr::Conn(RuntimeErr::SqlxError(err))`. `Arc::into_inner` only succeeds when the error `Arc` has exactly one owner; otherwise it returns `None` and the `expect` panics. The library assumes sqlx errors are uniquely owned when converting a connection failure into a `sqlx::Error` for sea_schema.
Source
Thrown at sea-orm-sync/src/database/sea_schema_shim.rs:83
fn map_result(result: Result<Vec<QueryResult>, DbErr>) -> Result<Vec<SqlxRow>, SqlxError> {
match result {
Ok(rows) => Ok(rows
.into_iter()
.filter_map(|r| match r.row {
#[cfg(feature = "sqlx-mysql")]
QueryResultRow::SqlxMySql(r) => Some(SqlxRow::MySql(r)),
#[cfg(feature = "sqlx-postgres")]
QueryResultRow::SqlxPostgres(r) => Some(SqlxRow::Postgres(r)),
#[cfg(feature = "sqlx-sqlite")]
QueryResultRow::SqlxSqlite(r) => Some(SqlxRow::Sqlite(r)),
#[allow(unreachable_patterns)]
_ => None,
})
.collect()),
Err(err) => Err(match err {
DbErr::Conn(RuntimeErr::SqlxError(err)) => {
Arc::into_inner(err).expect("Should only have one owner")
}
DbErr::Exec(RuntimeErr::SqlxError(err)) => {
Arc::into_inner(err).expect("Should only have one owner")
}
DbErr::Query(RuntimeErr::SqlxError(err)) => {
Arc::into_inner(err).expect("Should only have one owner")
}
_ => SqlxError::AnyDriverError(Box::new(err)),
}),
}
}
View on GitHub (pinned to e29bcd1b41)
Solutions
- Upgrade sea-orm/sea-schema to the latest compatible versions.
- Ensure no custom middleware clones `DbErr` (and thus the inner `Arc<sqlx::Error>`) before the shim maps it.
- Patch the shim defensively: use `Arc::try_unwrap` with an `SqlxError::AnyDriverError` fallback instead of `expect`.
- File an upstream issue with the connection failure and backtrace if it occurs with stock usage.
Example fix
// before
DbErr::Conn(RuntimeErr::SqlxError(err)) => {
Arc::into_inner(err).expect("Should only have one owner")
}
// after
DbErr::Conn(RuntimeErr::SqlxError(err)) => {
Arc::try_unwrap(err)
.unwrap_or_else(|e| SqlxError::AnyDriverError(Box::new(DbErr::Conn(RuntimeErr::SqlxError(e)))))
} Defensive patterns
Strategy: try-catch
Validate before calling
// Ensure the sqlx connection is alive before schema discovery
conn.ping().map_err(|e| eprintln!("backend unreachable: {e}"))?; Type guard
fn conn_err_unique(err: &DbErr) -> bool {
matches!(err, DbErr::Conn(RuntimeErr::SqlxError(e))) && Arc::strong_count(e) == 1
} Try / catch
std::panic::catch_unwind(AssertUnwindSafe(|| discovery.query_all(select)))
.map_err(|_| anyhow!("panic in sea_schema sqlx shim"))?; Prevention
- Keep sqlx and sea-orm on compatible versions
- Avoid middleware that clones sqlx errors before the shim maps them
- Use catch_unwind around schema discovery in fault-tolerant services
- If it reproduces on stock usage, file an upstream bug with a backtrace
When it happens
Trigger: `query_all`/`query_all_raw` through the sea_schema `Connection` impl fails with `DbErr::Conn(RuntimeErr::SqlxError(...))` while another clone of the `Arc<sqlx::Error>` exists at mapping time.
Common situations: Hit during schema discovery over a sqlx-backed connection (MySQL/Postgres/SQLite) when the connection itself fails (disconnect, pool closed) and some layer (logging, pooling, retry logic) retains a clone of the error. Treat it as a library invariant bug rather than a user misconfiguration.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Should only have one owner
- Should only have one owner
- Not MySQL Connection
- Not Postgres Connection
- Not SQLite Connection
AI-assisted analysis of SeaQL/sea-orm@e29bcd1b41 (2026-09-10).
Data as JSON: /api/errors/edd303d4dcf28275.
Report an issue: GitHub.