nautechsystems/nautilus_trader · error · anyhow::Error
venue position ID differs across fill group
Error message
venue position ID differs across fill group
What it means
A synthesized OrderStatusReport for an orphan fill group must resolve to one position. This ensure! checks that all fills in the group report the same venue_position_id (earlier code already bail!s if it is missing entirely); differing position IDs mean the group spans multiple positions and cannot be aggregated into one order report.
Source
Thrown at crates/live/src/execution/manager.rs:1295
"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"
);
}
anyhow::ensure!(
first.instrument_id == instrument.id(),
"instrument metadata does not match fill group"
);
let (quantity, notional) = fills.iter().try_fold(
(Decimal::ZERO, Decimal::ZERO),
|(quantity, notional), fill| {
let fill_quantity = fill.last_qty.as_decimal();
let quantity = quantity.checked_add(fill_quantity).ok_or_else(|| {
anyhow::anyhow!("fill quantity overflow while aggregating fill group")
})?;
View on GitHub (pinned to 18893faf8b)
Solutions
- Ensure the adapter's account configuration (netting vs hedging) matches the actual venue account mode so fills map to a single position ID per order.
- Group fills by venue_position_id as part of the key so each group has one consistent position ID.
- Check that venue_position_id is parsed from the venue's fill report rather than derived inconsistently per fill.
- Re-run reconciliation after correcting account mode / position ID derivation so stale groups are rebuilt from fresh venue reports.
Example fix
// before: group keyed without position let key = (account_id, venue_order_id); // after: require a single position ID per group let key = (account_id, venue_order_id, fill.venue_position_id?);
Defensive patterns
Strategy: validation
Validate before calling
let pos_ids: std::collections::HashSet<_> = fills.iter().map(|f| f.venue_position_id).collect();
assert!(pos_ids.len() == 1 && pos_ids.iter().all(|p| p.is_some()), "fill group has missing or mixed venue position IDs: {:?}", pos_ids); Type guard
fn single_position_group(fills: &[&FillReport]) -> bool {
fills[0].venue_position_id.is_some()
&& fills.iter().all(|f| f.venue_position_id == fills[0].venue_position_id)
} Prevention
- Match the trader's account configuration (netting vs hedging) to the venue's actual account mode.
- Group fills by venue_position_id so each group resolves to exactly one position.
- Re-run reconciliation after any account-mode or adapter-version change instead of reusing old fill groups.
When it happens
Trigger: FillReports grouped together share order/account/instrument keys but their venue_position_id values differ — e.g. fills that were assigned to different OMS positions by the venue, or None vs Some mismatches that slipped past grouping.
Common situations: Netting vs hedging account-mode mismatches between the venue account and the Nautilus reconciliation config; venue splitting one order's fills across positions after account mode changes; adapter changes to position-ID derivation between versions.
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
- venue position ID is missing
- venue order ID differs across fill group
- client order ID differs across fill group
- order side differs across fill group
- Position id should be generated. Hedging Oms type order matc
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/02173d92ce5730cf.
Report an issue: GitHub.