nautechsystems/nautilus_trader · error

validated above

Error message

validated above

What it means

In submit_order_list (live WebSocket batching), build_ws_place_params constructs the JSON payload per order. Its error cases were already filtered out when valid_orders was built, so the code expects success; a panic means the earlier filtering missed a case and validation drifted from payload construction.

Source

Thrown at crates/adapters/bybit/src/execution.rs:1753

        let mut client_order_ids = Vec::with_capacity(valid_orders.len());

        for order in &valid_orders {
            let bybit_side = BybitOrderSide::from(order.order_side());
            let position_idx = self.resolve_position_idx(
                instrument_id,
                bybit_side,
                order.is_reduce_only(),
                tp_sl.position_idx,
            );
            let params = Self::build_ws_place_params(
                order,
                product_type,
                raw_symbol,
                &tp_sl,
                position_idx,
                smp_type,
            )
            .expect("validated above");
            order_params.push(params);
            client_order_ids.push(order.client_order_id());
        }

        let ws_trade = self.ws_trade.clone();
        let dispatch_state = Arc::clone(&self.dispatch_state);

        self.spawn_task("submit_order_list", async move {
            let req_ids = BybitWebSocketClient::batch_request_ids(product_type, order_params.len());
            for (req_id, chunk_cids) in req_ids.iter().zip(
                client_order_ids
                    .chunks(batch_send_limit(product_type))
                    .map(|chunk| chunk.to_vec()),
            ) {
                let chunk_voids = vec![None; chunk_cids.len()];
                dispatch_state.pending_requests.insert(
                    req_id.clone(),
                    (chunk_cids, chunk_voids, PendingOperation::Place),

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Compare the valid_orders filtering logic with build_ws_place_params' error branches and align them
  2. Handle the builder's Result explicitly and reject that order with an order-rejected event instead of panicking
  3. Add a test per order type covering filter + builder together
  4. Pin the adapter version known to match your order types; upgrade deliberately

Example fix

// before
let params = Self::build_ws_place_params(order, ...).expect("validated above");
// after
let params = Self::build_ws_place_params(order, ...)?; // or emit rejection for this order
order_params.push(params);
Defensive patterns

Strategy: validation

Validate before calling

// filter orders the same way build_ws_place_params does
let valid: Vec<_> = orders.into_iter()
    .filter(|o| matches!(o.order_type(), OrderType::Limit | OrderType::Market))
    .collect();

Type guard

fn is_submittable(order: &Order) -> bool {
    matches!(order.order_type(), OrderType::Limit | OrderType::Market)
        && order.order_side() != OrderSide::NoOrderSide
        && !order.quantity().is_zero()
}

Try / catch

let params = match Self::build_ws_place_params(order, ...) {
    Ok(p) => p,
    Err(e) => { emit_order_rejected(cid, e); continue; }
};

Prevention

When it happens

Trigger: Submitting an order list where an order passes the pre-filter (e.g. valid order type/price/TIF combination) but build_ws_place_params still rejects it — typically after one of the two was changed without the other.

Common situations: Adding a new order type or TP/SL variant handled in the builder but not in the valid_orders filter (or vice versa); instrument-specific constraints (e.g. missing price for LIMIT) not checked upstream.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/5c61781235c252bd. Report an issue: GitHub.