nautechsystems/nautilus_trader · error · anyhow::Error
submitted position ID {submitted_position_id} conflicts with
Error message
submitted position ID {submitted_position_id} conflicts with canonical Binance Futures venue position ID {venue_position_id}; omit position_id while use_position_ids=true, or set use_position_ids=false for virtual hedging What it means
When the venue has a canonical position ID (use_position_ids=true), any caller-supplied position_id on a submitted order must match it exactly. validate_submit_position_id rejects a submitted PositionId that differs from the venue's, because split identity would break position tracking; the fix is to omit position_id and let the adapter assign the venue ID, or disable venue position IDs entirely.
Source
Thrown at crates/adapters/binance/src/futures/execution.rs:1347
) -> anyhow::Result<(Option<BinancePositionSide>, Option<PositionId>)> {
let position_side =
determine_position_side(is_hedge_mode, order.order_side(), order.is_reduce_only());
let venue_position_id = make_venue_position_id(
use_position_ids,
order.instrument_id(),
Some(position_side.unwrap_or(BinancePositionSide::Both)),
)?;
Ok((position_side, venue_position_id))
}
fn validate_submit_position_id(
submitted_position_id: Option<PositionId>,
venue_position_id: Option<PositionId>,
) -> anyhow::Result<()> {
if let (Some(submitted_position_id), Some(venue_position_id)) =
(submitted_position_id, venue_position_id)
{
anyhow::ensure!(
submitted_position_id == venue_position_id,
"submitted position ID {submitted_position_id} conflicts with canonical Binance Futures venue position ID {venue_position_id}; omit position_id while use_position_ids=true, or set use_position_ids=false for virtual hedging",
);
}
Ok(())
}
fn build_futures_order_list_batch(
orders: &[OrderAny],
is_hedge_mode: bool,
close_position: bool,
price_match: Option<BinancePriceMatch>,
product_type: BinanceProductType,
use_gtd: bool,
ts_now: UnixNanos,
) -> Result<Vec<BatchOrderItem>, String> {
if orders.len() > 5 {
return Err(format!(View on GitHub (pinned to 18893faf8b)
Solutions
- Remove the explicit position_id from the SubmitOrder request so the adapter uses the canonical venue position ID.
- Set use_position_ids=false in the Binance Futures exec client config if you need strategy-managed (virtual) position IDs.
- Make the submitted position_id equal to the venue position ID if identity must be pinned deliberately.
- Audit strategy code for hardcoded PositionId values and route them through the exec client's identity scheme.
Example fix
// before
client.submit_order(order, Some(PositionId::new("MY-POS-1")), None);
// after
client.submit_order(order, None, None); // let venue position ID be assigned Defensive patterns
Strategy: validation
Validate before calling
if cfg.use_position_ids {
assert!(submit.position_id.is_none() || submit.position_id == Some(venue_position_id),
"custom position_id not allowed with use_position_ids=true");
} Prevention
- Omit position_id on submissions when use_position_ids=true
- Set use_position_ids=false for strategy-managed virtual position IDs
- Grep strategies for hardcoded PositionId values before deploying to Binance Futures
When it happens
Trigger: submit_order or submit_order_list called (directly or via a strategy) with an explicit custom PositionId on an order while the Binance Futures exec client runs with use_position_ids=true and a venue position ID exists for the instrument/side.
Common situations: Strategies that hardcode position IDs ported from another adapter or from backtests with virtual hedging; copying code that sets position_id while the config later enabled use_position_ids=true.
Related errors
- unknown position_side
- incompatible cached {position_side:?} position IDs for {inst
- Unsupported `OrderSide` for Binance: {value:?}
- Invalid order side: {e}
- Binance Futures goodTillDate must be smaller than {BINANCE_G
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/fa080d999bac644d.
Report an issue: GitHub.