SeaQL/sea-orm · error

Must be valid

Error message

Must be valid

What it means

`delete_by_id` builds an `ActiveModel` for the primary key, then calls `Delete::one(am).validate()` and unwraps with `.expect("Must be valid")`. The validation asserts that the delete statement has a WHERE clause on the primary key. Panicking here means the constructed delete was structurally invalid — in practice only reachable if the primary key columns could not be set (e.g. arity mismatch path fell through) or the model type is misconfigured.

Solutions

  1. Pass the primary key value in the exact form the entity expects (single value for single-column key, tuple for composite keys).
  2. Regenerate/fix the entity's PrimaryKey definition so it matches the database schema.
  3. Prefer `Entity::delete_by_id(pk).exec(db)` usage patterns from docs and verify the entity compiles tests that call delete_by_id.

Example fix

// before
MyEntity::delete_by_id((id,)) // tuple for single-column key is wrong
// after
MyEntity::delete_by_id(id) // plain value for single-column primary key
Defensive patterns

Strategy: validation

Validate before calling

// check arity of the key you are about to delete by
let expected: usize = <MyEntity::PrimaryKey as PrimaryKeyTrait>::ValueType::arity();
// single-column key: pass a plain value; composite: pass a tuple of the same length

Type guard

fn valid_delete_key<E: EntityTrait>(pk: E::PrimaryKey) -> bool { true } // compile-time: only correctly-typed keys convert

Try / catch

// delete_by_id panics internally, so validate types first; runtime errors from exec(db) are catchable:
match MyEntity::delete_by_id(pk).exec(db).await {
    Ok(res) => println!("deleted {}", res.rows_affected),
    Err(DbErr::RecordNotFound(_)) => { /* nothing to delete */ }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Calling `EntityTrait::delete_by_id(value)` where the supplied value cannot be converted into the primary key column set correctly, or a custom entity whose PrimaryKey definition is inconsistent so the ActiveModel is built without its key columns set.

Common situations: Deleting by a composite key while passing a single value, passing the wrong id type after a schema refactor, or hand-rolled entity definitions with broken primary key metadata.

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


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

Appendix: source

Thrown at sea-orm-sync/src/entity/base_entity.rs:1063

    /// #
    /// # Ok(())
    /// # }
    /// ```
    fn delete_by_id<T>(values: T) -> ValidatedDeleteOne<Self>
    where
        T: Into<<Self::PrimaryKey as PrimaryKeyTrait>::ValueType>,
    {
        let mut am = Self::ActiveModel::default();
        let mut keys = Self::PrimaryKey::iter();
        for v in values.into().into_value_tuple() {
            if let Some(key) = keys.next() {
                let col = key.into_column();
                am.set(col, v);
            } else {
                unreachable!("primary key arity mismatch");
            }
        }
        Delete::one(am).validate().expect("Must be valid")
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn test_delete_by_id_1() {
        use crate::tests_cfg::cake;
        use crate::{DbBackend, entity::*, query::*};
        assert_eq!(
            cake::Entity::delete_by_id(1)
                .build(DbBackend::Sqlite)
                .to_string(),
            r#"DELETE FROM "cake" WHERE "cake"."id" = 1"#,
        );
    }

    #[test]

View on GitHub (pinned to e29bcd1b41)