{"record":{"id":"8b3a8e712e7386c2","repo":"SeaQL/sea-orm","slug":"index-out-of-bounds-the-activehasmany-is-notset","errorCode":null,"errorMessage":"index out of bounds: the ActiveHasMany is NotSet (index: {index})","messagePattern":"index out of bounds: the ActiveHasMany is NotSet \\(index: (.+?)\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sea-orm-sync/src/entity/active_model_ex.rs","lineNumber":430,"sourceCode":"    }\n}\n\nimpl<E: EntityTrait> From<ActiveHasMany<E>> for Option<Vec<E::ActiveModelEx>> {\n    fn from(value: ActiveHasMany<E>) -> Self {\n        match value {\n            ActiveHasMany::NotSet => None,\n            ActiveHasMany::Replace(models) | ActiveHasMany::Append(models) => Some(models),\n        }\n    }\n}\n\nimpl<E: EntityTrait> Index<usize> for ActiveHasMany<E> {\n    type Output = E::ActiveModelEx;\n\n    fn index(&self, index: usize) -> &Self::Output {\n        match self {\n            ActiveHasMany::NotSet => {\n                panic!(\"index out of bounds: the ActiveHasMany is NotSet (index: {index})\")\n            }\n            ActiveHasMany::Replace(models) | ActiveHasMany::Append(models) => models.index(index),\n        }\n    }\n}\n\nimpl<E: EntityTrait> IndexMut<usize> for ActiveHasMany<E> {\n    fn index_mut(&mut self, index: usize) -> &mut Self::Output {\n        match self {\n            ActiveHasMany::NotSet => {\n                panic!(\"index out of bounds: the ActiveHasMany is NotSet (index: {index})\")\n            }\n            ActiveHasMany::Replace(models) | ActiveHasMany::Append(models) => {\n                models.index_mut(index)\n            }\n        }\n    }\n}","sourceCodeStart":412,"sourceCodeEnd":448,"githubUrl":"https://github.com/SeaQL/sea-orm/blob/e29bcd1b417c41a553b386fe94511d7c64a1c8ec/sea-orm-sync/src/entity/active_model_ex.rs#L412-L448","documentation":"The `Index<usize>` implementation for `ActiveHasMany<E>` panics when the relation state is `NotSet` — meaning no child models have been loaded or assigned yet — while code tries to read an element by index. The library cannot produce an element for a relation that was never populated, so it treats indexing as out of bounds.","triggerScenarios":"`active_model.children[index]` (or `.index(i)`) where `children` is an `ActiveHasMany` still in `NotSet` state — i.e. the relation was never set via `.replace(...)`/`.append(...)` nor loaded from the database before indexing.","commonSituations":"Indexing a has-many relation before calling a load/`with(...)` fetch; constructing a new ActiveModel from scratch and assuming children exist; relying on a relation that a previous save path left untouched.","solutions":["Populate or load the relation before indexing: use the loader API (`with(child::Entity)`) or assign via `.replace(models)`/`.append(model)`.","Check the state first with a match on `ActiveHasMany::NotSet` and handle the empty case instead of indexing.","Use `try_index`/fallible accessors or `as_slice().get(index)` if available, handling `None`.","Ensure the code path that was supposed to load children actually ran (don't skip the `with(...)` call)."],"exampleFix":"// before\nlet first = &post.comments[0]; // panics if comments is NotSet\n// after\nif let ActiveHasMany::Replace(models) | ActiveHasMany::Append(models) = &post.comments {\n    if let Some(first) = models.get(0) { /* ... */ }\n}","handlingStrategy":"type-guard","validationCode":"// Guard against NotSet before indexing\nlet items: Option<&Vec<child::ActiveModelEx>> = match &post.children {\n    ActiveHasMany::Replace(m) | ActiveHasMany::Append(m) => Some(m),\n    ActiveHasMany::NotSet => None,\n};","typeGuard":"fn as_loaded_slice<'a, E: EntityTrait>(r: &'a ActiveHasMany<E>) -> Option<&'a [E::ActiveModelEx]> {\n    match r { ActiveHasMany::Replace(m) | ActiveHasMany::Append(m) => Some(m), ActiveHasMany::NotSet => None }\n}","tryCatchPattern":"// Indexing panics; avoid try-catch, use the guard\nmatch as_loaded_slice(&post.children).and_then(|m| m.get(0)) {\n    Some(first) => {},\n    None => {} // handle unset/empty relation\n}","preventionTips":["Always eager-load has-many relations with .with(child::Entity) before reading them","Check the relation state instead of assuming it is populated","In tests/fixtures, explicitly replace() relations on new ActiveModels"],"tags":["index-out-of-bounds","panic","relation","has-many"],"backgroundTag":"index-out-of-bounds","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"}