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
- Compare the valid_orders filtering logic with build_ws_place_params' error branches and align them
- Handle the builder's Result explicitly and reject that order with an order-rejected event instead of panicking
- Add a test per order type covering filter + builder together
- 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
- Keep the order filter and payload builder in lockstep; test them together
- Cover every order type with an integration-style test
- Prefer graceful per-order rejection over expect in submission paths
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
- symbol checked for suffix during construction
- Stream receiver already taken or client not connected
- Cannot take ownership - other references exist
- book channel present
- slots lock poisoned
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/5c61781235c252bd.
Report an issue: GitHub.