{"record":{"id":"c8d00218258533b8","repo":"SeaQL/sea-orm","slug":"item-is-a-full-model-c8d002","errorCode":null,"errorMessage":"item is a full model","messagePattern":"item is a full model","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/entity/active_model.rs","lineNumber":1296,"sourceCode":"        let via_key = get_key_from_active_model(&right.from_col, &via)?;\n        if !leftover.iter().any(|t| t.1 == via_key) {\n            // if not already exist, save for insert\n            via_models.push(via);\n        }\n        if delete_leftover {\n            all_keys.insert(via_key);\n        }\n    }\n\n    if delete_leftover {\n        let mut to_delete = Vec::new();\n        let mut to_delete_am = Vec::new();\n        for (leftover, key) in leftover {\n            if !all_keys.contains(&key) {\n                to_delete.push(\n                    leftover\n                        .get_primary_key_value()\n                        .expect(\"item is a full model\"),\n                );\n                to_delete_am.push(leftover);\n            }\n        }\n        if !to_delete.is_empty() {\n            // run before_delete hooks\n            for am in to_delete_am.clone() {\n                am.before_delete(db).await?;\n            }\n            if db.support_returning() {\n                let deleted = J::delete_many()\n                    .filter_by_value_tuples(&to_delete, db.get_database_backend())\n                    .exec_with_returning(db)\n                    .await?;\n                // run after_delete hooks with the returned value if possible\n                for am in deleted {\n                    let am = am.into_active_model();\n                    let _ = am.after_delete(db).await?;","sourceCodeStart":1278,"sourceCodeEnd":1314,"githubUrl":"https://github.com/SeaQL/sea-orm/blob/e29bcd1b417c41a553b386fe94511d7c64a1c8ec/src/entity/active_model.rs#L1278-L1314","documentation":"`establish_links` unwraps `leftover.get_primary_key_value()` with `.expect(\"item is a full model\")` (src/entity/active_model.rs:1296). The precondition is that every leftover junction row is a fully-loaded Model (all columns present, including primary key). Panicking means a model without a complete primary key value was treated as a full model — normally impossible when models come straight from a DB query.","triggerScenarios":"Calling `insert_many`/link-establishing APIs (e.g. `save` with delete_leftover semantics) where a leftover junction Model lacks primary key values — e.g. an ActiveModel converted to Model prematurely, or a Model constructed in code with None/zeroed keys.","commonSituations":"Programmatically constructing junction Models instead of loading them; custom ORM behavior overrides that return partially-populated models into establish_links.","solutions":["Ensure the junction models passed through establish_links come from a database select so primary keys are populated.","Do not construct Models by hand for link sync; use ActiveModels.","Check that the junction entity's primary key is correctly declared (composite, auto_increment=false).","If using IntoActiveModel conversions, verify all PK columns were Set before conversion."],"exampleFix":"// before (hand-built model missing PK)\nlet j = junction::Model { post_id: 1, /* tag_id missing */ };\n// after\nlet j = junction::Entity::find_by_id((post.id, tag.id)).one(db)?.unwrap();","handlingStrategy":"validation","validationCode":"// ensure leftover models have complete primary keys before link sync\nfor m in leftovers {\n    assert!(m.get_primary_key_value().is_some(), \"junction model missing PK\");\n}","typeGuard":"fn is_full_model<M: ModelTrait>(m: &M) -> bool {\n    m.get_primary_key_value().is_some()\n}","tryCatchPattern":null,"preventionTips":["Load junction models from the DB rather than constructing them in code","Declare junction primary keys correctly (composite, auto_increment=false)","Avoid IntoActiveModel round-trips that drop Set primary keys"],"tags":["primary-key","panic","internal-invariant","many-to-many"],"backgroundTag":"internal-invariant-violation","analyzedSha":"e29bcd1b417c41a553b386fe94511d7c64a1c8ec","analyzedAt":"2026-09-10T11:31:52.468Z","contentChangedAt":"2026-09-10T11:31:52.468Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}