nautechsystems/nautilus_trader · error

fill {} is not in order history

Error message

fill {} is not in order history

What it means

When processing an order event that references positions (e.g. position splits/opens derived from a fill), the engine searches the order's event history for an existing Filled event with the same trade_id to obtain the originating fill's event_id. If no prior fill in the order's history matches the incoming event's trade_id, it raises "fill {trade_id} is not in order history".

Source

Thrown at crates/execution/src/engine/mod.rs:3870

        position_events
    }

    fn prepare_order_fill_void_positions(
        &self,
        order: &OrderAny,
        event: &OrderFillVoided,
    ) -> anyhow::Result<Vec<CorrectedPosition>> {
        let source_event_id = order
            .events()
            .into_iter()
            .find_map(|order_event| match order_event {
                OrderEventAny::Filled(fill) if fill.trade_id == event.trade_id => {
                    Some(fill.event_id)
                }
                _ => None,
            })
            .ok_or_else(|| anyhow::anyhow!("fill {} is not in order history", event.trade_id))?;

        let positions: Vec<Position> = {
            let cache = self.cache.borrow();
            cache
                .positions(
                    None,
                    Some(&event.instrument_id),
                    Some(&event.strategy_id),
                    Some(&event.account_id),
                    None,
                )
                .into_iter()
                .map(|position| position.cloned())
                .collect()
        };
        let mut fragments = Vec::new();

        for position in &positions {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Verify the original Fill event for that trade_id was applied to the order before this dependent event (event ordering).
  2. Rebuild/restore the cache so the order's full event history includes the referenced fill.
  3. Deduplicate broker fill reports so repeated trade_ids are not re-processed as new events.
  4. Check reconciliation logic to ensure fills from mass status are inserted into order history before fragment computation.
Defensive patterns

Strategy: validation

Validate before calling

// before dispatching a dependent event, confirm the fill exists in order history
if !order.events().iter().any(|ev| matches!(ev,
    OrderEventAny::Filled(f) if f.trade_id == event.trade_id))
{
    // apply or fetch the original fill first
}

Try / catch

match result {
    Err(e) if e.to_string().contains("is not in order history") => {
        // reload cache/replay fills, then retry the event
    }
    other => other?,
}

Prevention

When it happens

Trigger: Dispatching an order event whose trade_id does not correspond to any OrderEventAny::Filled already recorded on that order — e.g. a duplicate or replayed fill event, or an event arriving before the original fill was persisted.

Common situations: Reconciliation mass status replaying fills against orders whose history was not fully loaded from cache; duplicate broker fill reports with new trade ids; cache rebuilt without the original fill events; out-of-order event delivery from the venue.

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 nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/0e27be6f79cfd078. Report an issue: GitHub.