nautechsystems/nautilus_trader · error · anyhow::Error
position_side SHORT conflicts with positive position_amt
Error message
position_side SHORT conflicts with positive position_amt
What it means
Mirror case of error 1840: when use_position_ids=true and Binance reports positionSide=SHORT, the sign of position_amt must be negative (short positions on Binance carry a negative amount). A positive amount alongside a SHORT side marker is contradictory, so create_position_report rejects the position risk record instead of emitting an inconsistent report.
Source
Thrown at crates/adapters/binance/src/futures/execution.rs:1029
let entry_price: Decimal = position
.entry_price
.parse()
.context("invalid entry_price")?;
let position_side = if position_amount > Decimal::ZERO {
PositionSide::Long
} else {
PositionSide::Short
};
if self.config.use_position_ids {
match position.position_side {
Some(BinancePositionSide::Long) => anyhow::ensure!(
position_side == PositionSide::Long,
"position_side LONG conflicts with negative position_amt"
),
Some(BinancePositionSide::Short) => anyhow::ensure!(
position_side == PositionSide::Short,
"position_side SHORT conflicts with positive position_amt"
),
_ => {}
}
}
let venue_position_id = make_venue_position_id(
self.config.use_position_ids,
instrument_id,
position.position_side,
)?;
if let Some(venue_position_id) = venue_position_id {
self.ensure_cached_position_id_compatible(
instrument_id,
position_side,
venue_position_id,View on GitHub (pinned to 18893faf8b)
Solutions
- Confirm the account is in hedge mode consistently with adapter config (use_position_ids=true assumes hedge-mode style positionSide fields).
- Set use_position_ids=false in the exec client config to bypass side/ID consistency checks.
- Force a fresh reconciliation of position risk data to replace the stale snapshot.
- Close and flatten the affected position via the venue, then let the adapter rebuild state from an empty book.
Example fix
// keep hedge mode and venue IDs aligned
// before
BinanceFuturesExecClientConfig { use_position_ids: true } // account in one-way mode
// after
// switch Binance account to Hedge Mode, or:
BinanceFuturesExecClientConfig { use_position_ids: false } Defensive patterns
Strategy: validation
Validate before calling
if cfg.use_position_ids {
let amt: Decimal = position.position_amt.parse()?;
if position.position_side == Some(BinancePositionSide::Short) && amt > Decimal::ZERO {
log::warn!("inconsistent SHORT side with positive amt for {}", position.symbol);
}
} Prevention
- Verify hedge mode before enabling use_position_ids
- Force full re-reconciliation after changing position mode
- Flatten positions before switching account position mode
When it happens
Trigger: create_position_report called from generate_position_status_reports with position.position_side == Some(BinancePositionSide::Short) while position_amt parses to a positive value; usually from stale or partially updated position risk data, or from one-way-mode records mislabeled as SHORT.
Common situations: Account switched out of hedge mode leaving stale side metadata; manual trades in the Binance web UI while the adapter reconciles; dual-side position records where the closing leg has not yet been applied server-side.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- position_side LONG conflicts with negative position_amt
- actual order ID mismatch: expected {expected_actual_order_id
- actual order symbol mismatch: expected {}, was {}
- actual order side mismatch: expected {:?}, was {:?}
- incompatible cached {position_side:?} position IDs for {inst
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/41089c81ce5e4c8a.
Report an issue: GitHub.