SeaQL/sea-orm · error

Cannot unwrap ActiveValue::NotSet

Error message

Cannot unwrap ActiveValue::NotSet

What it means

ActiveValue::unwrap() extracts the inner Value from a Set or Unchanged ActiveValue. The library panics because NotSet means the field was never assigned a value, so there is nothing to unwrap. It is a deliberate programming-error signal, not a runtime failure.

Source

Thrown at src/entity/active_value.rs:291

    }

    /// Take ownership of the inner value, also setting self to `NotSet`
    pub fn take(&mut self) -> Option<V> {
        match std::mem::take(self) {
            ActiveValue::Set(value) | ActiveValue::Unchanged(value) => Some(value),
            ActiveValue::NotSet => None,
        }
    }

    /// Get an owned value of the [ActiveValue]
    ///
    /// # Panics
    ///
    /// Panics if it is [ActiveValue::NotSet]
    pub fn unwrap(self) -> V {
        match self {
            ActiveValue::Set(value) | ActiveValue::Unchanged(value) => value,
            ActiveValue::NotSet => panic!("Cannot unwrap ActiveValue::NotSet"),
        }
    }

    /// Take ownership of the inner value, consuming self
    pub fn into_value(self) -> Option<Value> {
        match self {
            ActiveValue::Set(value) | ActiveValue::Unchanged(value) => Some(value.into()),
            ActiveValue::NotSet => None,
        }
    }

    /// Wrap the [Value] into a `ActiveValue<Value>`
    pub fn into_wrapped_value(self) -> ActiveValue<Value> {
        match self {
            Self::Set(value) => ActiveValue::set(value.into()),
            Self::Unchanged(value) => ActiveValue::unchanged(value.into()),
            Self::NotSet => ActiveValue::not_set(),
        }

View on GitHub (pinned to e29bcd1b41)

Solutions

  1. Use try_get() / into_value() (fallible or Option-returning accessors) instead of unwrap()
  2. Check the field with matches!(v, ActiveValue::Set(_) | ActiveValue::Unchanged(_)) before unwrapping
  3. Ensure the field was explicitly .set(...) or .insert(...) on the ActiveModel before unwrapping
  4. Convert with try_into_model() to get a Result instead of panicking

Example fix

// before
let v = user.name.unwrap();
// after
let v = user.name.into_value().unwrap_or_default();
Defensive patterns

Strategy: type-guard

Validate before calling

fn is_set<V>(v: &ActiveValue<V>) -> bool { matches!(v, ActiveValue::Set(_) | ActiveValue::Unchanged(_)) }

Type guard

fn try_value<V>(v: &ActiveValue<V>) -> Option<&V> { match v { ActiveValue::Set(x) | ActiveValue::Unchanged(x) => Some(x), _ => None } }

Try / catch

// Panics cannot be caught idiomatically; prefer fallible accessors
let v = user.name.into_value().ok_or_else(|| anyhow!("name not set"))?;

Prevention

When it happens

Trigger: Calling .unwrap() on an ActiveValue that was never set — e.g. a freshly created ActiveModel field left at NotSet, or reading back a field skipped by NotSetErr/Unset().

Common situations: Copying values between models where some fields were never assigned; iterating model fields with the value() accessor and forgetting some are unset; converting an ActiveModel back to a Model with try_into_model missing so NotSet fields remain.

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/785df825b7b4dbf8. Report an issue: GitHub.