nautechsystems/nautilus_trader · error · anyhow::Error

instrument ID differs across fill group

Error message

instrument ID differs across fill group

What it means

Same consistency guard family: every fill in the group must share the instrument_id of the first fill. This fires when fills for different instruments were placed in the same group, so a single OrderStatusReport could not represent them.

Source

Thrown at crates/live/src/execution/manager.rs:1279

    }

    fn create_orphan_fill_order_report(
        fills: &[&FillReport],
        instrument: &InstrumentAny,
    ) -> anyhow::Result<OrderStatusReport> {
        let Some(first) = fills.first() else {
            anyhow::bail!("fill group is empty");
        };
        let venue_position_id = first
            .venue_position_id
            .ok_or_else(|| anyhow::anyhow!("venue position ID is missing"))?;

        for fill in fills.iter().skip(1) {
            anyhow::ensure!(
                fill.account_id == first.account_id,
                "account ID differs across fill group"
            );
            anyhow::ensure!(
                fill.instrument_id == first.instrument_id,
                "instrument ID differs across fill group"
            );
            anyhow::ensure!(
                fill.venue_order_id == first.venue_order_id,
                "venue order ID differs across fill group"
            );
            anyhow::ensure!(
                fill.client_order_id == first.client_order_id,
                "client order ID differs across fill group"
            );
            anyhow::ensure!(
                fill.order_side == first.order_side,
                "order side differs across fill group"
            );
            anyhow::ensure!(
                fill.venue_position_id == first.venue_position_id,
                "venue position ID differs across fill group"

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Add instrument_id to the fill grouping key.
  2. Confirm venue order ID uniqueness semantics and namespace by instrument if needed.
  3. Check recent changes to reconciliation/grouping code or adapter ID mapping.
  4. Report as a bug if stock grouping mixes instruments.

Example fix

// before
let group_key = fill.venue_order_id;
// after
let group_key = (fill.instrument_id, fill.venue_order_id);
Defensive patterns

Strategy: validation

Validate before calling

anyhow::ensure!(fills.iter().all(|f| f.instrument_id == fills[0].instrument_id), "mixed instruments in group");

Type guard

fn single_instrument(fills: &[&FillReport]) -> bool { fills.iter().all(|f| f.instrument_id == fills.first().unwrap().instrument_id) }

Try / catch

if let Err(e) = create_orphan_fill_order_report(&fills, &instrument) { log::error!("fill group inconsistent: {e}"); return; }

Prevention

When it happens

Trigger: Fill reports for different instrument_ids sharing the grouping key — usually a grouping key that omits instrument_id, or venue order IDs reused across instruments.

Common situations: Adapters whose order IDs are only unique per instrument (common on some venues); reconciliation batches combining multiple instruments; grouping-key refactors that dropped the instrument component.

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