nautechsystems/nautilus_trader · error
asset_id must be resolved for unsided cancellation
Error message
asset_id must be resolved for unsided cancellation
What it means
When cancel_all_orders is issued without a side, the Polymarket execution client must know which market (asset_id) to cancel for, since the venue API cancels per token/market. The code expects the asset_id to have been resolved from the command context; if it is None the panic fires.
Source
Thrown at crates/adapters/polymarket/src/execution/cancellations.rs:361
}
}
if side.is_some() && orders.is_empty() {
return Ok(());
}
let clock = self.clock;
let submitter = self.submitter.clone();
let emitter = self.emitter.clone();
let instrument_id = cmd.instrument_id;
let spawned = self.spawn_task("cancel_all_orders", async move {
let _cancel_guard = cancel_guard;
let response = match side {
None => {
let asset_id = asset_id
.as_deref()
.expect("asset_id must be resolved for unsided cancellation");
submitter.cancel_market_orders(asset_id).await
}
Some(_) => {
let venue_order_ids = orders
.iter()
.map(|(venue_order_id, _)| venue_order_id.to_string())
.collect::<Vec<_>>();
let order_id_refs =
venue_order_ids.iter().map(String::as_str).collect::<Vec<_>>();
submitter.cancel_orders(&order_id_refs).await
}
};
match response {
Ok(response) => {
for (venue_order_id, order) in &orders {
let venue_order_id_str = venue_order_id.to_string();View on GitHub (pinned to 18893faf8b)
Solutions
- Pass an instrument_id (or asset_id) to cancel_all_orders so the market can be resolved.
- Iterate over open instruments and issue one unsided cancel per market instead of a global cancel.
- If a side-specific cancel is acceptable, pass Some(side) so asset_id is not required.
Example fix
// before
exec_client.cancel_all_orders(None, None); // panics: no market context
// after
for instrument_id in open_instrument_ids {
exec_client.cancel_all_orders(Some(instrument_id), None);
} Defensive patterns
Strategy: validation
Validate before calling
# before calling the execution client
if instrument_id is None and asset_id is None:
raise ValueError("cancel_all_orders requires an instrument_id/asset_id when side is None")
exec_client.cancel_all_orders(instrument_id, None) Try / catch
try:
exec_client.cancel_all_orders(instrument_id, None)
except Exception as e:
self.log.error(f"cancel-all failed for {instrument_id}: {e}") Prevention
- Always scope cancel-all requests to a specific instrument/market.
- Register instruments before issuing cancels so asset_id resolution succeeds.
- For global flattening, loop per instrument rather than relying on one command.
When it happens
Trigger: Submitting a CancelAllOrders command with side=None and no instrument_id/token resolvable to a Polymarket asset_id — e.g. a global cancel-all with no market context.
Common situations: Calling cancel_all_orders() without an instrument_id from a strategy running on multiple markets; UI/dashboard issuing a blanket 'flatten all' cancel; instrument_id not registered so asset_id lookup yielded None.
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
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/b584bebdf26e11f5.
Report an issue: GitHub.