SeaQL/sea-orm · error

Cannot borrow ActiveValue::NotSet

Error message

Cannot borrow ActiveValue::NotSet

What it means

ActiveValue<V>::as_ref() borrows the inner value only when the value is Set or Unchanged; the reference cannot exist for the NotSet variant because no value is stored. The panic is the deliberately non-fallible counterpart to try_as_ref, fired when the caller borrowed an ActiveValue that was never assigned (still NotSet), e.g. reading a field of a freshly built ActiveModel before setting it.

Source

Thrown at src/entity/active_value.rs:612

            ActiveValue::Set(value) | ActiveValue::Unchanged(value) => value,
            ActiveValue::NotSet => None,
        }
    }
}

impl<V> std::convert::AsRef<V> for ActiveValue<V>
where
    V: Into<Value>,
{
    /// # Panics
    ///
    /// Panics if it is [ActiveValue::NotSet].
    ///
    /// See [ActiveValue::try_as_ref] for a fallible non-panicking version.
    fn as_ref(&self) -> &V {
        match self {
            ActiveValue::Set(value) | ActiveValue::Unchanged(value) => value,
            ActiveValue::NotSet => panic!("Cannot borrow ActiveValue::NotSet"),
        }
    }
}

impl<V> PartialEq for ActiveValue<V>
where
    V: Into<Value> + std::cmp::PartialEq,
{
    fn eq(&self, other: &Self) -> bool {
        match (self, other) {
            (ActiveValue::Set(l), ActiveValue::Set(r)) => l == r,
            (ActiveValue::Unchanged(l), ActiveValue::Unchanged(r)) => l == r,
            (ActiveValue::NotSet, ActiveValue::NotSet) => true,
            _ => false,
        }
    }
}

View on GitHub (pinned to e29bcd1b41)

Solutions

  1. Use try_as_ref() and handle the Err(NotSet) case instead of as_ref().
  2. Ensure the field is set (Set/Unchanged) before borrowing — check with is_set()/is_not_set() or set a default first.
  3. For optional access, use the existing opt accessor which returns Option<&V> and yields None for NotSet.

Example fix

// before
let v = user.email.as_ref();
// after
let v = user.email.try_as_ref().expect("email must be set");
Defensive patterns

Strategy: type-guard

Validate before calling

if !matches!(av, ActiveValue::Set(_) | ActiveValue::Unchanged(_)) { return Err("field not set"); }

Type guard

fn try_borrow<V>(v: &ActiveValue<V>) -> Option<&V> { v.try_as_ref().ok() }

Try / catch

// Prefer try_as_ref
let v = user.email.try_as_ref().map_err(|_| anyhow!("email not set"))?;

Prevention

When it happens

Trigger: Calling .as_ref() (directly or via generic code taking &V) on an ActiveValue in the NotSet state.

Common situations: Generic helper functions borrowing ActiveValue fields on partially-filled ActiveModels; comparing or hashing fields where some were never set.

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