nautechsystems/nautilus_trader · error
Either venue_order_id or client_order_id must be provided
Error message
Either venue_order_id or client_order_id must be provided
What it means
`modify_order` on the Binance futures HTTP client requires at least one order identifier. Binance's API accepts either `orderId` or `origClientOrderId`; if both `venue_order_id` and `client_order_id` are `None`, the adapter cannot build a valid modify request and fails fast with `anyhow::ensure!`.
Solutions
- Pass the `VenueOrderId` obtained from the submit response/report.
- Or pass the original `ClientOrderId` used at submission (it is broker-encoded automatically).
- Add caller-side code that stores at least one of the two identifiers on every order before any modify path can run.
Example fix
// before client.modify_order(instrument_id, None, None, side, qty, price).await?; // after client.modify_order(instrument_id, Some(venue_order_id), None, side, qty, price).await?;
Defensive patterns
Strategy: validation
Validate before calling
fn ensure_modify_id(venue: Option<&VenueOrderId>, client: Option<&ClientOrderId>) -> Result<(), String> {
if venue.is_none() && client.is_none() {
return Err("modify_order needs venue_order_id or client_order_id".into());
}
Ok(())
} Type guard
fn has_order_id(venue: &Option<VenueOrderId>, client: &Option<ClientOrderId>) -> bool {
venue.is_some() || client.is_some()
} Try / catch
match client.modify_order(instrument_id, venue_id, client_id, side, qty, price).await {
Err(e) if e.to_string().contains("must be provided") => {
// look up an ID from the order cache before retrying
}
other => other?,
} Prevention
- Persist both venue and client order IDs at submit time.
- Never call modify on orders whose submit was never acknowledged.
- Wrap modify calls with an ID-presence check.
When it happens
Trigger: Calling `modify_order(instrument_id, None, None, order_side, quantity, price)` — e.g. an execution layer that resolved neither identifier, or a partially constructed OrderModify command with empty IDs.
Common situations: Passing None after a failed order-ID lookup; constructing the modify call programmatically with optional IDs that were never populated; race where the client order ID was never persisted and the venue ID was not yet received.
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
- Algo order type requires a trigger price
- Either venue_order_id or client_order_id must be provided
- invalid O-format broker client order ID payload length
- missing broker client order ID signal
- missing raw broker client order ID payload
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/01b10be98118be58.
Report an issue: GitHub.
Appendix: source
Thrown at crates/adapters/binance/src/futures/http/client.rs:2391
///
/// # Errors
///
/// Returns an error if:
/// - Neither venue_order_id nor client_order_id is provided.
/// - The instrument is not cached.
/// - The request fails.
#[expect(clippy::too_many_arguments)]
pub async fn modify_order(
&self,
account_id: AccountId,
instrument_id: InstrumentId,
venue_order_id: Option<VenueOrderId>,
client_order_id: Option<ClientOrderId>,
order_side: OrderSide,
quantity: Quantity,
price: Price,
) -> anyhow::Result<OrderStatusReport> {
anyhow::ensure!(
venue_order_id.is_some() || client_order_id.is_some(),
"Either venue_order_id or client_order_id must be provided"
);
let (symbol, price_precision, size_precision) =
self.cached_precisions_by_id(instrument_id)?;
let binance_side = BinanceSide::try_from(order_side)?;
let order_id = venue_order_id
.map(|id| id.inner().parse::<i64>())
.transpose()
.map_err(|_| anyhow::anyhow!("Invalid venue order ID"))?;
let params = BinanceModifyOrderParams {
symbol,
order_id,
orig_client_order_id: client_order_idView on GitHub (pinned to 18893faf8b)