nautechsystems/nautilus_trader · error
cannot claim venue order ID {} for settlement order {client_
Error message
cannot claim venue order ID {} for settlement order {client_order_id}: {e} What it means
NautilusTrader's option settlement plan executor claims the venue order ID for each settlement leg in the execution cache. This error means `cache.add_venue_order_id` returned an error, so the venue order ID could not be associated with the settlement order's client order ID (typically because the client order ID is unknown to the cache or the venue order ID is already claimed by another order).
Source
Thrown at crates/execution/src/matching_engine/settlement.rs:188
self.dispatch_order_event(OrderEventAny::Filled(leg.fill));
}
Ok(())
}
fn option_register_settlement_plan(&self, plan: &OptionSettlementPlan) -> anyhow::Result<()> {
for leg in &plan.legs {
let client_order_id = leg.order.client_order_id();
let mut cache = self.cache.borrow_mut();
cache
.add_order(leg.order.clone(), leg.fill.position_id, None, false)
.map_err(|e| {
anyhow::anyhow!("cannot add settlement order {client_order_id}: {e}")
})?;
cache
.add_venue_order_id(&client_order_id, &leg.fill.venue_order_id, false)
.map_err(|e| {
anyhow::anyhow!(
"cannot claim venue order ID {} for settlement order {client_order_id}: {e}",
leg.fill.venue_order_id
)
})?;
}
Ok(())
}
fn option_should_exercise(&self, underlying_price: Price) -> bool {
let strike = match self.instrument.strike_price() {
Some(p) => p.as_decimal(),
None => return false,
};
let spot = underlying_price.as_decimal();
match self.instrument.option_kind() {
Some(OptionKind::Call) => spot > strike,
Some(OptionKind::Put) => strike > spot,
None => false,View on GitHub (pinned to 18893faf8b)
Solutions
- Ensure each settlement leg's client order ID exists in the cache before applying the plan (the settlement order must have been added first).
- Check for duplicate venue order IDs across legs or against previously settled orders; regenerate unique venue order IDs per fill.
- Log the underlying cache error `{e}` to identify whether it is a missing order or an ID conflict, and fix the registration sequence accordingly.
Example fix
// before: applying plan without registering the settlement order first
apply_settlement_plan(plan);
// after: register each leg's client order and venue order ID in order
for leg in &plan.legs {
cache.add_order(...)?:
cache.add_venue_order_id(&leg.client_order_id, &leg.fill.venue_order_id, false)?;
} Defensive patterns
Strategy: try-catch
Validate before calling
if cache.client_order_id(&leg.fill.venue_order_id).is_some() {
return Err(anyhow!("venue order ID {} already claimed", leg.fill.venue_order_id));
} Try / catch
match cache.add_venue_order_id(&client_order_id, &leg.fill.venue_order_id, false) {
Ok(_) => {},
Err(e) => log::error!("settlement claim failed: {e}"),
} Prevention
- Register the settlement order in the cache before claiming its venue order ID.
- Guarantee venue order ID uniqueness across settlement legs and runs.
- Avoid running concurrent settlement flows for the same instrument.
When it happens
Trigger: Calling `option_apply_settlement_plan` (via `option_register_settlement_plan`) when a leg's client_order_id is not registered in the cache, or when `leg.fill.venue_order_id` was already claimed by a different client order ID.
Common situations: Replaying or restarting a settlement flow with cached/duplicate venue order IDs; registering a settlement plan whose client order IDs were never added to the cache; concurrent settlement of the same expired option position from two processes.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- DataActor {} must be registered before calling `cache()` - t
- Order {client_order_id} not found
- Position {position_id} not found
- Order for {} not found to determine position ID
- Order {client_order_id} not found in cache.
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/dfbc0348897a2610.
Report an issue: GitHub.