nautechsystems/nautilus_trader · error
Order invariant violated: no events
Error message
Order invariant violated: no events
What it means
OrderAny::init_event returns the first event, which by the order-model invariant is always OrderInitialized. It unwraps with expect("Order invariant violated: no events") and panics when the order's event list is empty, and with the sibling message when the first event is a different type. Since from_events rejects empty input, an OrderAny with no events should never exist — hitting this means the object was constructed or mutated outside the documented paths.
Source
Thrown at crates/model/src/orders/any.rs:113
.map_err(|source| OrderReplayError::ApplyFailed { source })?;
}
Ok(order)
}
/// Returns a reference to the [`crate::events::OrderInitialized`] event.
///
/// This is always the first event in the order's event list (invariant).
///
/// # Panics
///
/// Panics if the first event is not `OrderInitialized` (violates invariant).
#[must_use]
pub fn init_event(&self) -> &crate::events::OrderInitialized {
match self
.events()
.first()
.expect("Order invariant violated: no events")
{
OrderEventAny::Initialized(init) => init,
_ => panic!("Order invariant violated: first event must be OrderInitialized"),
}
}
/// Assigns the order to the list identified by `id`.
///
/// # Panics
///
/// Panics if the order has no events or its first event is not `OrderInitialized`.
pub fn set_order_list_id(&mut self, id: OrderListId) {
let order: &mut OrderCore = match self {
Self::Limit(order) => order,
Self::LimitIfTouched(order) => order,
Self::Market(order) => order,
Self::MarketIfTouched(order) => order,
Self::MarketToLimit(order) => order,View on GitHub (pinned to 18893faf8b)
Solutions
- Always construct OrderAny via OrderAny::from_events with OrderInitialized as the first event — it returns a proper OrderReplayError::EmptyInput instead of an order that panics later.
- Check the deserialization/restore path so the first persisted event (Initialized) is included and not filtered out.
- Verify no code clears or truncates the `events` vec on a live order.
- Where you cannot guarantee the invariant, call order.events().first() yourself and handle None before calling init_event.
- Prefer OrderInitialized event data directly from your creation site if you already hold it, rather than re-reading from the order.
Example fix
// before
let init = order.init_event(); // panics if events empty
// after
let init = order.events().first().map(|e| match e {
OrderEventAny::Initialized(init) => init.clone(),
_ => panic!("first event must be Initialized"),
});
match init {
Some(init) => { /* use init */ }
None => return Err("order has no events".into()),
} Defensive patterns
Strategy: type-guard
Validate before calling
if order.events().is_empty() {
return Err("order has no events; cannot read init_event".into());
}
let init = order.init_event(); Type guard
fn has_init_event(order: &OrderAny) -> bool {
matches!(order.events().first(), Some(OrderEventAny::Initialized(_)))
} Try / catch
// Prefer from_events, which returns Result instead of panicking:
let order = match OrderAny::from_events(events) {
Ok(o) => o,
Err(OrderReplayError::EmptyInput) => return Err("no order events".into()),
Err(e) => return Err(e.into()),
};
let init = order.init_event(); Prevention
- Only build orders via OrderAny::from_events with OrderInitialized first.
- Never truncate or clear the order's event list after creation.
- Check deserialization paths so the Initialized event is never dropped.
- Guard with events().first() when reconstructing orders from unknown sources.
When it happens
Trigger: Calling init_event on an OrderAny that was built with zero events (e.g. via unsafe/Default-ish paths, manual struct construction, or code that cleared `events`), or on a partially deserialized order where the Initialized event was dropped.
Common situations: Custom deserialization that skips the init event; tests or tools constructing OrderAny fields directly; cache/restore code that applied events into a fresh order without seeding OrderInitialized; version-skewed persisted state.
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 nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/d4dc12fa83e1880b.
Report an issue: GitHub.