nautechsystems/nautilus_trader · error · anyhow::Error
fill {} order side or venue order ID differs from cached ord
Error message
fill {} order side or venue order ID differs from cached order What it means
After resolving the client_order_id, the manager looks up the cached order and verifies the fill report matches it on instrument_id, order_side, and account_id. A mismatch means the fill cannot belong to that cached order, so it aborts rather than corrupting position state.
Source
Thrown at crates/live/src/execution/manager.rs:2834
&self,
report: &mut FillReport,
venue_reports: &[PositionStatusReport],
) -> anyhow::Result<PositionFillReportPreparation> {
let cache = self.cache.borrow();
let venue_client_order_id = cache.client_order_id(&report.venue_order_id).copied();
if let (Some(report_client_order_id), Some(venue_client_order_id)) =
(report.client_order_id, venue_client_order_id)
{
anyhow::ensure!(
report_client_order_id == venue_client_order_id,
"fill {} client order ID {report_client_order_id} conflicts with venue order mapping {venue_client_order_id}",
report.trade_id,
);
}
let client_order_id = report.client_order_id.or(venue_client_order_id);
let order = client_order_id.and_then(|id| cache.order(&id));
if let Some(order) = &order {
anyhow::ensure!(
order.instrument_id() == report.instrument_id
&& order.order_side() == report.order_side
&& order
.account_id()
.is_none_or(|account_id| account_id == report.account_id)
&& order
.venue_order_id()
.is_none_or(|venue_order_id| venue_order_id == report.venue_order_id),
"fill {} conflicts with cached order {}",
report.trade_id,
order.client_order_id(),
);
}
let hedge_context = report.venue_position_id.is_some()
|| venue_reports
.iter()
.any(|venue_report| venue_report.venue_position_id.is_some());View on GitHub (pinned to 18893faf8b)
Solutions
- Fix the adapter's field mapping so instrument_id, order_side, and account_id in reports match the submitted order
- Verify instrument ID mapping/symbology resolves to the same nautilus instrument the order used
- Check account_id assignment in the adapter's account-state/report handling
- Re-reconcile the cached order if a legitimate order amendment changed its attributes
Example fix
// before (adapter hardcodes side) report.order_side = OrderSide::Buy; // after report.order_side = map_venue_side(venue_fill.side);
Defensive patterns
Strategy: validation
Validate before calling
let order = cache.order(&client_order_id);
if let Some(o) = order {
assert_eq!(o.instrument_id(), report.instrument_id);
assert_eq!(o.order_side(), report.order_side);
} Type guard
fn report_matches_order(report: &TradeReport, order: &OrderAny) -> bool {
order.instrument_id() == report.instrument_id
&& order.order_side() == report.order_side
&& order.account_id().map_or(true, |a| a == report.account_id)
} Prevention
- Centralize side/instrument/account mapping in one adapter function used by all report types
- Add adapter unit tests asserting mapped report fields equal submitted order fields
- Use canonical nautilus instrument IDs derived from a single symbology table
When it happens
Trigger: A fill report arrives for a cached client_order_id but with a different instrument_id, an opposite/other order_side, or a different account_id than the cached order records. Caused by adapter field mapping bugs, wrong instrument lookup, or reports routed to the wrong client account.
Common situations: Multi-account live setups where the adapter stamps the wrong account_id; symbol-mapping bugs that resolve the wrong instrument; venue side conventions (BUY/SELL) translated incorrectly by a custom adapter.
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
- fill {} client order ID {report_client_order_id} conflicts w
- fill {} position ID {venue_position_id} conflicts with cache
- fill {} maps to position {position_id}, which is not cached
- fill {} maps to position {position_id} with a different acco
- fill {} maps to non-open position {position_id}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/230a49731a3bd28e.
Report an issue: GitHub.