SeaQL/sea-orm · error

Should not retrieve last_insert_id this way

Error message

Should not retrieve last_insert_id this way

What it means

ExecResult::last_insert_id() only yields a value for backends that report it natively (MySQL). On PostgreSQL the driver returns no last_insert_id — the inserted key is delivered through RETURNING via exec_with_returning / exec_with_returning_keys — so calling this getter on a Postgres result hits an intentional panic. The at-fault input is an ExecResult produced by a PostgreSQL insert.

Source

Thrown at sea-orm-sync/src/executor/execute.rs:51

}

// ExecResult //

impl ExecResult {
    /// The auto-increment primary key value assigned by the database on the
    /// most recent `INSERT`.
    ///
    /// # Panics
    ///
    /// PostgreSQL does not expose `last_insert_id` directly — use
    /// `exec_with_returning` / `exec_with_returning_keys` instead.
    pub fn last_insert_id(&self) -> u64 {
        match &self.result {
            #[cfg(feature = "sqlx-mysql")]
            ExecResultHolder::SqlxMySql(result) => result.last_insert_id(),
            #[cfg(feature = "sqlx-postgres")]
            ExecResultHolder::SqlxPostgres(_) => {
                panic!("Should not retrieve last_insert_id this way")
            }
            #[cfg(feature = "sqlx-sqlite")]
            ExecResultHolder::SqlxSqlite(result) => {
                let last_insert_rowid = result.last_insert_rowid();
                if last_insert_rowid < 0 {
                    unreachable!("negative last_insert_rowid")
                } else {
                    last_insert_rowid as u64
                }
            }
            #[cfg(feature = "rusqlite")]
            ExecResultHolder::Rusqlite(result) => {
                let last_insert_rowid = result.last_insert_rowid;
                if last_insert_rowid < 0 {
                    unreachable!("negative last_insert_rowid")
                } else {
                    last_insert_rowid as u64
                }

View on GitHub (pinned to e29bcd1b41)

Solutions

  1. On PostgreSQL use exec_with_returning or exec_with_returning_keys to obtain the inserted primary key.
  2. Branch on DbBackend (or ExecResultHolder variant) before reading last_insert_id, and use the backend-appropriate API.
  3. Avoid this getter in backend-agnostic insert code; use the higher-level insert()/save() APIs that already return the model with its new id.
Defensive patterns

Strategy: type-guard

When it happens

Trigger: Thrown at sea-orm-sync/src/executor/execute.rs:51 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of SeaQL/sea-orm@e29bcd1b41 (2026-09-10). Data as JSON: /api/errors/03332e6ff4f6aa57. Report an issue: GitHub.