SeaQL/sea-orm · error

called `HasOne::unwrap()` on an `Unloaded` value

Error message

called `HasOne::unwrap()` on an `Unloaded` value

What it means

HasOne<E>::unwrap() panics because the variant is Unloaded: the has-one relation was never eagerly loaded (no .with(...) on the query before unwrap), so there is no contained model. It indicates the relation access happened before/without loading, not that the related row is missing.

Source

Thrown at src/entity/compound/has_one.rs:77

    pub fn into_option(self) -> Option<E::ModelEx> {
        match self {
            Self::Loaded(Some(model)) => Some(*model),
            Self::Unloaded | Self::Loaded(None) => None,
        }
    }

    /// Take ownership of the contained Model, if loaded, leaving `Unloaded` in place.
    pub fn take(&mut self) -> Option<E::ModelEx> {
        std::mem::take(self).into_option()
    }

    /// # Panics
    ///
    /// Panics if called on an `Unloaded` or `Loaded(None)` value.
    pub fn unwrap(self) -> E::ModelEx {
        match self {
            Self::Loaded(Some(model)) => *model,
            Self::Unloaded => panic!("called `HasOne::unwrap()` on an `Unloaded` value"),
            Self::Loaded(None) => panic!("called `HasOne::unwrap()` on a `Loaded(None)` value"),
        }
    }
}

impl<E> HasOne<E>
where
    E: EntityTrait,
    E::ActiveModelEx: From<E::ModelEx>,
{
    pub fn into_active_model(self) -> ActiveHasOne<E> {
        match self {
            Self::Loaded(Some(model)) => ActiveHasOne::set(Some(*model)),
            Self::Unloaded | Self::Loaded(None) => ActiveHasOne::NotSet,
        }
    }
}

View on GitHub (pinned to e29bcd1b41)

Solutions

  1. Eager-load with .with(profile::Entity) in the query
  2. Call .load(db).await? on the HasOne before unwrap()
  3. Use try_unwrap() / is_loaded() checks instead of unwrap()

Example fix

// before
let profile = user.profile.unwrap();
// after
let user = user::Entity::load().filter_by_id(id).with(profile::Entity).one(db).await?;
let profile = user.profile.unwrap();
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

fn loaded<E>(h: &HasOne<E>) -> Option<&E::ModelEx> { h.as_loaded() }

Try / catch

let profile = user.profile.load(db).await?.unwrap();

Prevention

When it happens

Trigger: Calling .unwrap() on a has_one relation field that was not included in the .with() chain of the loading query.

Common situations: Fetching a user without its profile relation then calling profile.unwrap(); partial eager-load lists; refactors that drop a .with() call.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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