nautechsystems/nautilus_trader · error · anyhow::Error

account ID differs across fill group

Error message

account ID differs across fill group

What it means

create_orphan_fill_order_report validates that every fill in a group shares the same account_id as the first fill; this ensure! fires when fills from different accounts were grouped together. It is a consistency guard so the synthesized OrderStatusReport is unambiguous.

Source

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

        ReconciliationResult {
            events,
            external_orders,
        }
    }

    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"

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Include account_id in the fill grouping key so groups never mix accounts.
  2. Verify adapter/account configuration so fills are tagged with the correct account.
  3. Audit venue behavior if the venue genuinely reuses order IDs across accounts.
  4. Report as a bug if stock grouping logic mixes accounts.

Example fix

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

Strategy: validation

Validate before calling

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

Type guard

fn single_account(fills: &[&FillReport]) -> bool { fills.iter().all(|f| f.account_id == fills.first().unwrap().account_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 from two different account_ids sharing the same grouping key (e.g. same venue_order_id reused across accounts, or a grouping key that omits account_id).

Common situations: Multi-account setups where the venue reuses order IDs across accounts; adapters mixing fills from several accounts into one reconciliation batch; grouping-key bugs after config changes (e.g. account routing changes).

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