SeaQL/sea-orm · error

index out of bounds: the HasMany is Unloaded (index: {index}

Error message

index out of bounds: the HasMany is Unloaded (index: {index})

What it means

Indexing a HasMany<E> with [] requires the relation to be loaded and the index within range. If the HasMany is Unloaded (never fetched) there is no backing vector, so indexing panics with this message.

Source

Thrown at src/entity/compound/has_many.rs:102

    }
}

impl<E: EntityTrait> From<HasMany<E>> for Option<Vec<E::ModelEx>> {
    fn from(value: HasMany<E>) -> Self {
        match value {
            HasMany::Loaded(models) => Some(models),
            HasMany::Unloaded => None,
        }
    }
}

impl<E: EntityTrait> Index<usize> for HasMany<E> {
    type Output = E::ModelEx;

    fn index(&self, index: usize) -> &Self::Output {
        match self {
            HasMany::Unloaded => {
                panic!("index out of bounds: the HasMany is Unloaded (index: {index})")
            }
            HasMany::Loaded(items) => items.index(index),
        }
    }
}

impl<E: EntityTrait> IntoIterator for HasMany<E> {
    type Item = E::ModelEx;
    type IntoIter = std::vec::IntoIter<E::ModelEx>;

    fn into_iter(self) -> Self::IntoIter {
        match self {
            HasMany::Loaded(models) => models.into_iter(),
            HasMany::Unloaded => Vec::new().into_iter(),
        }
    }
}

View on GitHub (pinned to e29bcd1b41)

Solutions

  1. Eager-load with .with(items::Entity) on the query
  2. Call .load(db).await? on the HasMany before indexing
  3. Use .as_ref() / try accessors to get Option<&[Model]> and check bounds

Example fix

// before
let first = user.posts[0];
// after
let posts = user.posts.try_get().unwrap_or_default();
if let Some(first) = posts.first() { /* ... */ }
Defensive patterns

Strategy: validation

Validate before calling

if !user.posts.is_loaded() { return Err("posts not loaded"); }

Type guard

fn loaded_items<E: EntityTrait>(h: &HasMany<E>) -> &[E::ModelEx] { h.as_loaded().unwrap_or(&[]) }

Try / catch

let items = user.posts.load(db).await?; let first = items.first().ok_or_else(|| anyhow!("no posts"))?;

Prevention

When it happens

Trigger: Using my_model.items[0] (Index<usize>) on a has_many relation that was never loaded via .with(...) or .load().

Common situations: Accessing child collections without eager loading; forgetting the relation in the .with() chain; calling index before an awaited load completes.

Related errors


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