nautechsystems/nautilus_trader · error · anyhow::Error
venue position ID is missing
Error message
venue position ID is missing
What it means
When building an orphan-fill OrderStatusReport, each FillReport must carry a venue_position_id (needed to attribute the synthetic order report to a position). This error is raised when the first fill in the group has None for that field, so a coherent report cannot be constructed.
Source
Thrown at crates/live/src/execution/manager.rs:1272
"Reconciliation complete for {venue}: reconciled={orders_reconciled}, external={external_orders_created}, open={open_orders_initialized}, fills={fills_applied}, positions={positions_created}, skipped={orders_skipped_duplicate}, filtered={orders_skipped_filtered}",
);
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"
);View on GitHub (pinned to 18893faf8b)
Solutions
- Ensure the adapter populates venue_position_id on all FillReports it generates.
- If the venue never provides position IDs, skip the orphan-fill grouping path for those fills instead of treating it as an error.
- Check for recent venue API/adapter version changes that dropped the field.
- Report as a bug if the adapter is supposed to always set it.
Example fix
// before
let venue_position_id = first.venue_position_id.ok_or_else(|| anyhow!("venue position ID is missing"))?;
// after
let Some(venue_position_id) = first.venue_position_id else {
log::warn!("fill has no venue position ID; skipping orphan fill grouping");
return Ok(());
}; Defensive patterns
Strategy: validation
Validate before calling
if fills.first().and_then(|f| f.venue_position_id).is_none() { log::warn!("fill lacks venue_position_id; skipping orphan grouping"); return Ok(()); } Type guard
fn has_position_id(f: &FillReport) -> bool { f.venue_position_id.is_some() } Try / catch
match create_orphan_fill_order_report(&fills, &instrument) { Err(e) if e.to_string().contains("position ID is missing") => log::warn!("adapter missing venue_position_id"), Err(e) => return Err(e), Ok(r) => {/* use r */} } Prevention
- Ensure adapters always populate venue_position_id on fills
- Skip orphan-fill grouping for venues that never report position IDs
- Watch for venue API changes that drop the field
When it happens
Trigger: A FillReport with venue_position_id = None reaches create_orphan_fill_order_report — typically from venues/adapters that do not populate position IDs on fill reports, or from netting venues where position ID is optional.
Common situations: Adapters that omit venue position IDs in fill data; venue API changes removing/renaming the position ID field; reconciliation over fills from a venue that never reports position IDs.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- account ID differs across fill group
- instrument ID differs across fill group
- venue position ID differs across fill group
- Position id should be generated. Hedging Oms type order matc
- Binance Futures position request has unresolved instrument {
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/f2665cc3fd3fbe04.
Report an issue: GitHub.