nautechsystems/nautilus_trader · error
fill raw bounds pre-checked
Error message
fill raw bounds pre-checked
What it means
When applying an OrderFilled event, filled() sums the raw quantity values with checked_quantity_quantity_raw_sum and unwraps the result, asserting the raw bounds were validated earlier in the fill path (quantity can't exceed raw u64 bounds at the order's precision). If the check fails here, an upstream pre-check was skipped or the fill is pathological.
Source
Thrown at crates/model/src/orders/mod.rs:1269
if event.reconciliation && !self.filled_qty.is_zero() && event.quantity == self.filled_qty {
self.status = OrderStatus::Filled;
self.ts_closed = Some(event.ts_event);
}
if let Some(venue_order_id) = &event.venue_order_id
&& (self.venue_order_id.is_none()
|| venue_order_id != self.venue_order_id.as_ref().unwrap())
{
self.venue_order_id = Some(*venue_order_id);
self.venue_order_ids.push(*venue_order_id);
}
self.is_quote_quantity = event.is_quote_quantity;
}
fn filled(&mut self, event: &OrderFilled, source_status: OrderStatus) {
let raw = checked_quantity_raw_sum(self.filled_qty.raw, event.last_qty.raw)
.expect("fill raw bounds pre-checked");
let new_filled_qty = Quantity::from_raw(raw, self.filled_qty.precision);
// Calculate overfill if any
if new_filled_qty > self.quantity {
let overfill_raw = new_filled_qty.raw - self.quantity.raw;
self.overfill_qty = quantity_from_domain_raw(
self.overfill_qty.raw.saturating_add(overfill_raw),
self.filled_qty.precision,
);
}
let new_leaves_qty = self.leaves_qty.saturating_sub(event.last_qty);
if new_filled_qty >= self.quantity {
self.status = OrderStatus::Filled;
self.ts_closed = Some(event.ts_event);
} else if new_leaves_qty.is_zero() && !self.voided_qty.is_zero() {
self.status = OrderStatus::Voided;View on GitHub (pinned to 18893faf8b)
Solutions
- Validate each fill's last_qty against the remaining quantity (leaves_qty) before applying the OrderFilled event
- Use try_from / checked arithmetic when constructing events from external venue data
- For replay, use the library's replay/adjustment APIs (e.g. apply adjustment paths) rather than direct event application with unvalidated quantities
Example fix
// before
order.apply(event); // OrderFilled with unvalidated qty
// after
if event.last_qty > order.leaves_qty() {
// clamp, reject, or log the anomalous fill
return;
}
order.apply(event); Defensive patterns
Strategy: validation
Validate before calling
// Rust: before applying OrderFilled assert!(event.last_qty <= order.leaves_qty(), "fill exceeds remaining quantity"); order.apply(event);
Type guard
fn fill_valid(o: &dyn Order, ev: &OrderFilled) -> bool { ev.last_qty <= o.leaves_qty() } Prevention
- Validate venue fills against remaining quantity before applying
- Use checked constructors when converting external quantities to Quantity
- Route anomalous fills to reconciliation instead of direct application
When it happens
Trigger: Applying an OrderFilled whose last_qty, added to the running filled_qty, overflows/underflows the raw fixed-precision bounds — i.e. a fill not pre-validated against the order quantity.
Common situations: Feeding synthetic or replayed fill events with quantities beyond the order's size; venue backfill producing fills exceeding total quantity at extreme precision; custom event replay code bypassing the normal fill validation.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- raw wei value exceeds unsigned 128-bit range
- DurationNanos overflow in from_micros
- {e}
- Quantity overflow for ticks={ticks}, decimals={decimals}: {e
- invalid quantity `{value}` at precision {precision}: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/9466e4ef87255234.
Report an issue: GitHub.