nautechsystems/nautilus_trader · error
Order modification rejected: {reason}
Error message
Order modification rejected: {reason} What it means
Raised by modify_order when BitMEX accepts the amend request but returns an order whose ordStatus is 'Rejected'. The adapter maps this venue-level rejection into a Rust error, using ordRejReason if present (otherwise 'No reason provided'). The request technically succeeded at HTTP level but the modification was refused by the venue.
Source
Thrown at crates/adapters/bitmex/src/http/client.rs:2000
}
if let Some(price) = price {
params.price(price.as_f64());
}
if let Some(trigger_price) = trigger_price {
params.stop_px(trigger_price.as_f64());
}
let params = params.build().map_err(|e| anyhow::anyhow!(e))?;
let order: BitmexOrder = self.inner.amend_order_response(params).await?;
if order.ord_status == Some(BitmexOrderStatus::Rejected) {
let reason = order
.ord_rej_reason
.map_or_else(|| "No reason provided".to_string(), |r| r.to_string());
anyhow::bail!("Order modification rejected: {reason}");
}
let instrument = self.instrument_from_cache(instrument_id.symbol.inner())?;
let ts_init = self.generate_ts_init();
parse_order_status_report(&order, &instrument, &self.order_type_cache, ts_init)
}
/// Query a single order by client order ID or venue order ID.
///
/// # Errors
///
/// Returns an error if:
/// - Credentials are missing.
/// - The request fails.
/// - The API returns an error.
pub async fn query_order(
&self,View on GitHub (pinned to 18893faf8b)
Solutions
- Inspect the returned reason string in the error message to identify the venue's rejection cause
- Re-query the order status to confirm its current state before retrying the amend
- Validate the new quantity/price against the instrument's limits before calling modify_order
- Handle the race where the order has already filled — treat as a no-op or cancel flow
Example fix
// before
let report = client.modify_order(instrument_id, None, Some(vid), Some(new_qty), None, None).await?;
// after
let current = client.request_order_status_report(instrument_id, None, Some(vid)).await?;
if current.order_status != OrderStatus::Accepted { return Ok(current); }
let report = client.modify_order(instrument_id, None, Some(vid), Some(new_qty), None, None).await?; Defensive patterns
Strategy: try-catch
Validate before calling
let current = client.request_order_status_report(instrument_id, client_order_id.clone(), venue_order_id.clone()).await?;
if current.order_status == OrderStatus::Filled || current.order_status == OrderStatus::Canceled {
return Ok(current); // nothing to amend
} Type guard
fn amendable(report: &OrderStatusReport) -> bool {
matches!(report.order_status, OrderStatus::Accepted | OrderStatus::PartiallyFilled)
} Try / catch
match client.modify_order(...).await {
Ok(report) => { /* handle */ }
Err(e) if e.to_string().starts_with("Order modification rejected:") => {
let reason = e.to_string();
// re-query order state and decide: retry, cancel, or alert
}
Err(e) => return Err(e),
} Prevention
- Re-check order status before amending to avoid racing fills
- Validate new quantity/price against instrument tick size and limits
- Log the venue rejection reason from the error message for post-mortem
When it happens
Trigger: Amending an order in a way BitMEX rejects: modifying a filled/canceled order, changing quantity/price to invalid values, or amending during certain market states. Any amend response with ordStatus==Rejected triggers it.
Common situations: Race conditions where the order fills just before the amend arrives; price/qty outside instrument limits; amending orders that are already terminal.
Related errors
- Order rejected: {reason}
- `peg_offset_value` requires `peg_price_type`
- Pegged orders only supported for LIMIT order type, was {orde
- {secret_var} is required when {key_var} is provided
- {key_var} is required when {secret_var} is provided
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/8535a20f9513759e.
Report an issue: GitHub.