nautechsystems/nautilus_trader · warning
Skipping non-trade execution: {:?}
Error message
Skipping non-trade execution: {:?} What it means
parse_fill_report only converts BitMEX execution records whose exec_type is Trade into FillReports. Funding, settlement, and other non-trade execution rows are rejected with this bail so they never produce synthetic fills. It signals the caller passed an execution record that is legitimately not a trade.
Source
Thrown at crates/adapters/bitmex/src/http/parse.rs:1089
/// # Errors
///
/// Currently this function does not return errors as all fields are handled gracefully,
/// but returns `Result` for future error handling compatibility.
///
/// Parse a BitMEX execution into a Nautilus `FillReport` using instrument scaling.
///
/// # Errors
///
/// Returns an error when the execution does not represent a trade or lacks required identifiers.
pub fn parse_fill_report(
exec: &BitmexExecution,
instrument: &InstrumentAny,
ts_init: UnixNanos,
) -> anyhow::Result<FillReport> {
// Skip non-trade executions (funding, settlements, etc.)
// Trade executions have exec_type of Trade and must have order_id
if !matches!(exec.exec_type, BitmexExecType::Trade) {
anyhow::bail!("Skipping non-trade execution: {:?}", exec.exec_type);
}
// 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)View on GitHub (pinned to 18893faf8b)
Solutions
- Filter executions on exec_type == Trade before requesting parse (the adapter's list-level parser skips these; only direct calls see the error)
- If calling parse_fill_report directly, pre-check matches!(exec.exec_type, BitmexExecType::Trade) and skip non-trades
- Treat this bail as an expected skip, not a failure: log and continue processing the remaining executions
- If funding/settlement records are needed, use a wallet/transaction endpoint rather than the execution endpoint
Example fix
// before
for exec in executions {
fills.push(parse_fill_report(&exec, &instrument, ts_init)?);
}
// after
for exec in executions {
if !matches!(exec.exec_type, BitmexExecType::Trade) {
continue; // funding/settlement entries
}
fills.push(parse_fill_report(&exec, &instrument, ts_init)?);
} Defensive patterns
Strategy: validation
Validate before calling
fn is_trade_exec(exec: &BitmexExecution) -> bool {
matches!(exec.exec_type, BitmexExecType::Trade)
}
// executions.iter().filter(|e| is_trade_exec(e)).map(parse_fill_report...) Type guard
fn as_trade(exec: &BitmexExecution) -> Option<&BitmexExecution> {
matches!(exec.exec_type, BitmexExecType::Trade).then_some(exec)
} Try / catch
match parse_fill_report(exec, instrument, ts_init) {
Ok(fill) => fills.push(fill),
Err(e) if e.to_string().starts_with("Skipping non-trade execution") => {
debug!("skipped non-trade exec {}: {:?}", exec.exec_id, exec.exec_type);
}
Err(e) => return Err(e),
} Prevention
- Filter exec_type == Trade before feeding executions to the fill parser
- Expect funding/settlement rows whenever requests span funding intervals
- Use wallet/transaction endpoints for funding data instead of execution history
- Keep a skip-count metric so silent skips of real fills are noticed
When it happens
Trigger: request_fill_reports iterating a BitMEX /execution or /execution/tradeHistory response that contains funding or settlement entries (exec_type != Trade), or a test feeding a non-Trade execution into parse_fill_report.
Common situations: Downloading fill history across a funding interval so funding entries appear in the response; settlement transactions after contract expiry; wallet adjustment rows mixed into execution history.
Related errors
- Skipping execution without side: {:?}
- 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/cbfbe0a6c373cc32.
Report an issue: GitHub.