nautechsystems/nautilus_trader · error · anyhow::Error
fill {} without a venue position ID would cross position {po
Error message
fill {} without a venue position ID would cross position {position_id} What it means
When a fill has no venue_position_id, the manager infers its position from the order. This check rejects an inferred fill whose side is opposite the position's side with quantity exceeding the position's open quantity - meaning the fill would flip/cross the position rather than reduce it, which the no-position-ID inference path does not allow.
Source
Thrown at crates/live/src/execution/manager.rs:2903
let position = cache.position(&position_id).ok_or_else(|| {
anyhow::anyhow!(
"fill {} maps to position {position_id}, which is not cached",
report.trade_id,
)
})?;
anyhow::ensure!(
position.account_id == report.account_id
&& position.instrument_id == report.instrument_id,
"fill {} maps to position {position_id} with a different account or instrument",
report.trade_id,
);
anyhow::ensure!(
position.is_open(),
"fill {} maps to non-open position {position_id}",
report.trade_id,
);
anyhow::ensure!(
!position.is_opposite_side(report.order_side) || report.last_qty <= position.quantity,
"fill {} without a venue position ID would cross position {position_id}",
report.trade_id,
);
report.venue_position_id = Some(position_id);
Ok(PositionFillReportPreparation::Ready)
}
#[cfg(feature = "node")]
fn has_active_inferred_fill(order: &OrderAny) -> anyhow::Result<bool> {
let events = order.events();
let trade_ids = order.trade_ids();
let Some((first, remaining)) = events.split_first() else {
return Ok(false);
};
let mut projected = OrderAny::from_events(vec![(*first).clone()]).map_err(|e| {
anyhow::anyhow!(View on GitHub (pinned to 18893faf8b)
Solutions
- Have the adapter populate venue_position_id on fills so attribution is explicit instead of inferred
- Ensure cached position quantity is accurate via reconciliation before sending oversized closing orders
- Size closing orders to the actual open position quantity, or split orders so no fill crosses flat
- Configure hedging mode if the strategy intentionally holds opposite-side exposure
Example fix
// before (oversized close, no position ID) let qty = Quantity::from(2 * position.quantity); // after let qty = position.quantity; // close exactly, avoid crossing
Defensive patterns
Strategy: validation
Validate before calling
if report.venue_position_id.is_none() {
if let Some(pos) = cache.position(&position_id) {
let would_cross = pos.is_opposite_side(report.order_side) && report.last_qty > pos.quantity;
assert!(!would_cross);
}
} Prevention
- Have the adapter always report venue_position_id when the venue provides one
- Size closing orders to the cached open quantity
- Reconcile position quantities after missed-fill incidents
- Use hedging mode for strategies that intentionally reverse exposure
When it happens
Trigger: report.venue_position_id is None, the order maps to position_id, the fill side is opposite to position.side, and report.last_qty > position.quantity. Happens when a closing order over-fills past flat (venue supports position flip) but the adapter provides no position ID, or when the cached position quantity is stale/undersized.
Common situations: Trading venues that allow flipping a position in one fill while the adapter doesn't report position IDs; stale cached position quantity after missed fills; submitting a larger closing order than the open position without letting the adapter attribute the resulting fill.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- fill {} client order ID {report_client_order_id} conflicts w
- fill {} order side or venue order ID differs from cached ord
- 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
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/b8118db515e0568d.
Report an issue: GitHub.