SeaQL/sea-orm · error

Already checked arity

Error message

Already checked arity

What it means

`get_primary_key_value` in `src/entity/model.rs:90` iterates the entity's primary-key columns and calls `cols.next().expect("Already checked arity")` inside a `next!` macro. The `match` on `PrimaryKeyArity::ARITY` guarantees the iterator has exactly that many items, so the expect documents an internal invariant. It only fires if the entity's `PrimaryKeyTrait`/`PrimaryKeyArity` impl is inconsistent (declared arity does not match the actual number of key columns).

Source

Thrown at src/entity/model.rs:90

        find_linked_recursive(initial_query, link)
    }

    /// Delete a model
    async fn delete<'a, A, C>(self, db: &'a C) -> Result<DeleteResult, DbErr>
    where
        Self: IntoActiveModel<A>,
        C: ConnectionTrait,
        A: ActiveModelTrait<Entity = Self::Entity> + ActiveModelBehavior + Send + 'a,
    {
        self.into_active_model().delete(db).await
    }

    /// Get the primary key value of the Model
    fn get_primary_key_value(&self) -> ValueTuple {
        let mut cols = <Self::Entity as EntityTrait>::PrimaryKey::iter();
        macro_rules! next {
            () => {
                self.get(cols.next().expect("Already checked arity").into_column())
            };
        }
        match <<<Self::Entity as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::ValueType as PrimaryKeyArity>::ARITY {
            1 => {
                let s1 = next!();
                ValueTuple::One(s1)
            }
            2 => {
                let s1 = next!();
                let s2 = next!();
                ValueTuple::Two(s1, s2)
            }
            3 => {
                let s1 = next!();
                let s2 = next!();
                let s3 = next!();
                ValueTuple::Three(s1, s2, s3)
            }

View on GitHub (pinned to e29bcd1b41)

Solutions

  1. Regenerate or correct the entity so `PrimaryKey` enum variants match the declared `PrimaryKeyArity` (SeaORM 2.0 new entity format).
  2. Update `sea-orm-io` to the version matching your `sea-orm` version so generated arity is correct.
  3. Verify the `#[sea_orm(primary_key)]` attribute is present on the PK field(s) of the model.

Example fix

// before (hand-written, arity says 1 but two pk columns)
impl PrimaryKeyTrait for PrimaryKey { type ValueType = i32; type Arity = PrimaryKeyArity::One; }
// after (regenerated entity matching model)
#[sea_orm(primary_key)]
pub id: i32,
// PrimaryKey::Id with PrimaryKeyArity::One
Defensive patterns

Strategy: type-guard

Validate before calling

// Check the entity's declared PK arity matches the key fields at startup
let arity = <<MyEntity as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::ValueType::ARITY;
debug_assert_eq!(arity, <MyEntity::PrimaryKey as PrimaryKeyTrait>::iter().count() as usize);

Type guard

fn pk_arity_matches<E: EntityTrait>() -> bool {
    <<E as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::ValueType::ARITY
        == <E::PrimaryKey as PrimaryKeyTrait>::iter().count()
}

Prevention

When it happens

Trigger: Calling `get_primary_key_value()` (directly or via save/delete/update of a `Model`) on an entity whose `PrimaryKey::iter()` yields fewer columns than `PrimaryKeyArity::ARITY` declares — e.g. a hand-written or code-generated broken primary-key impl.

Common situations: Hand-rolled entity definitions, entities generated by an outdated `sea-orm- io` version, or macro-generated code where the PK columns and arity desync after editing the model.

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/06764886cff518d6. Report an issue: GitHub.