nautechsystems/nautilus_trader · warning
Skipping execution without side: {:?}
Error message
Skipping execution without side: {:?} What it means
parse_fill_report requires a side to map the execution onto an OrderSide; an execution record with side == None is rejected with this bail because a fill cannot be attributed to buy/sell without it. BitMEX occasionally emits execution rows (funding, adjustments, some liquidation entries) that carry no side.
Source
Thrown at crates/adapters/bitmex/src/http/parse.rs:1109
// Additional check: skip executions without order_id (likely funding/settlement)
let order_id = exec.order_id.ok_or_else(|| {
anyhow::anyhow!("Skipping execution without order_id: {:?}", exec.exec_type)
})?;
let account_id = bitmex_account_id(exec.account);
let instrument_id = instrument.id();
let venue_order_id = VenueOrderId::new(order_id.to_string());
// trd_match_id might be missing for some execution types, use exec_id as fallback
let trade_id = TradeId::new(
exec.trd_match_id
.or(Some(exec.exec_id))
.ok_or_else(|| anyhow::anyhow!("Fill missing both trd_match_id and exec_id"))?
.to_string(),
);
// Skip executions without side (likely not trades)
let Some(side) = exec.side else {
anyhow::bail!("Skipping execution without side: {:?}", exec.exec_type);
};
let order_side = OrderSide::from(side);
let last_qty = parse_signed_contracts_quantity(exec.last_qty, instrument);
let last_px = Price::new(exec.last_px, instrument.price_precision());
// Map BitMEX currency to standard currency code
let settlement_currency_str = exec.settl_currency.unwrap_or(Ustr::from("XBT")).as_str();
let mapped_currency = map_bitmex_currency(settlement_currency_str);
let currency = get_currency(&mapped_currency);
let commission = Money::new(exec.commission.unwrap_or(0.0), currency);
let liquidity_side = parse_liquidity_side(&exec.last_liquidity_ind);
let client_order_id = exec.cl_ord_id.map(ClientOrderId::new);
let venue_position_id = None; // Not applicable on BitMEX
let ts_event = exec.transact_time.map_or(ts_init, UnixNanos::from);
Ok(FillReport::new(
account_id,
instrument_id,View on GitHub (pinned to 18893faf8b)
Solutions
- Skip executions where exec.side is None before calling parse_fill_report
- Log the exec_id of side-less executions and verify against BitMEX's dashboard whether they represent real fills
- Re-fetch the execution via /execution/tradeHistory, which usually populates side for genuine trades
- If side is genuinely absent for a known trade, infer it from order side or position effect in surrounding records rather than guessing inside the parser
Example fix
// before
let fill = parse_fill_report(&exec, &instrument, ts_init)?;
// after
let Some(side) = exec.side else {
tracing::warn!("skipping execution {} without side", exec.exec_id);
continue;
};
let fill = parse_fill_report(&exec, &instrument, ts_init)?; Defensive patterns
Strategy: validation
Validate before calling
fn parseable_fill(exec: &BitmexExecution) -> bool {
matches!(exec.exec_type, BitmexExecType::Trade) && exec.side.is_some()
}
// only call parse_fill_report when parseable_fill(&exec) Type guard
fn side_of(exec: &BitmexExecution) -> Option<BitmexSide> {
exec.side
} Try / catch
match parse_fill_report(exec, instrument, ts_init) {
Ok(fill) => fills.push(fill),
Err(e) if e.to_string().contains("without side") => {
warn!("exec {} had no side; skipped", exec.exec_id);
}
Err(e) => return Err(e),
} Prevention
- Validate side is present along with exec_type before parsing
- Log exec_id of side-less rows and reconcile against the BitMEX dashboard
- Prefer /execution/tradeHistory which populates side for real trades
- Sanity-check test fixtures include side when mimicking trade executions
When it happens
Trigger: request_fill_reports encountering a Trade-typed execution record whose side field is null, or a directly constructed/test execution without side set.
Common situations: BitMEX returning execution rows with missing side during exchange data glitches; liquidation or adl entries lacking side; hand-built execution fixtures in tests missing the side field.
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
- Skipping non-trade execution: {:?}
- Order missing order_qty and cannot reconstruct (order_id={},
- Coinbase fill has unknown order side
- Failed to create price from fill px: {e}
- Failed to create quantity from fill sz: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/6578ea4741e9ae04.
Report an issue: GitHub.