nautechsystems/nautilus_trader · error
OTO parent not found
Error message
OTO parent not found
What it means
During order validation the matching engine found that an order has a parent_order_id, but the parent order either is missing from the cache or is not an OTO (One-Triggers-Other) contingent order. Because contingent-order bookkeeping depends on a valid OTO parent, the engine panics — the child order's contingency chain is broken. This is a defensive invariant protecting OTO lifecycle handling.
Source
Thrown at crates/execution/src/matching_engine/mod.rs:2840
if let Some(expiration_ns) = self.instrument.expiration_ns()
&& self.clock.borrow().timestamp_ns() >= expiration_ns
{
break 'validate Some(
format!(
"Contract {} has expired, expiration {expiration_ns}",
self.instrument.id(),
)
.into(),
);
}
}
// Contingent orders checks
if self.config.support_contingent_orders {
if let Some(parent_order_id) = order.parent_order_id() {
let parent_order = match self.order_snapshot(parent_order_id) {
Some(o) if o.contingency_type() == Some(ContingencyType::Oto) => o,
_ => panic!("OTO parent not found"),
};
let parent_filled_qty = parent_order.filled_qty();
if parent_order.status() == OrderStatus::Rejected && order.is_open() {
break 'validate Some(
format!("Rejected OTO order from {parent_order_id}").into(),
);
} else if parent_filled_qty.is_zero()
|| (self.config.oto_full_trigger
&& parent_filled_qty < parent_order.quantity())
{
log::info!(
"Pending OTO order {} triggers from {parent_order_id}",
order.client_order_id(),
);
return;
}
}View on GitHub (pinned to 18893faf8b)
Solutions
- Ensure the OTO parent order exists in the matching engine cache before submitting the child (submit parent first).
- Verify the parent's contingency_type is actually Oto; fix order construction so parent_order_id is only set on genuine OTO children.
- Enable cache persistence or rebuild contingent chains on startup so parents survive restarts.
- Reject/fix inbound orders whose parent_order_id cannot be resolved instead of forwarding them to the engine.
Example fix
// before child.parent_order_id = Some(random_id); // after assert_eq!(parent.contingency_type(), Some(ContingencyType::Oto)); child.parent_order_id = Some(parent.client_order_id()); // genuine OTO parent, cached first
Defensive patterns
Strategy: validation
Validate before calling
// before submitting an OTO child
let parent = cache.order(&parent_id);
let valid = matches!(parent, Some(o) if o.contingency_type() == Some(ContingencyType::Oto));
if !valid { return Err(anyhow!("OTO parent {parent_id} missing or not OTO")); } Type guard
fn is_cached_oto_parent(cache: &Cache, id: &ClientOrderId) -> bool {
matches!(cache.order(id), Some(o) if o.contingency_type() == Some(ContingencyType::Oto))
} Prevention
- Submit OTO parents before children and keep parents cached for the chain's lifetime.
- Only set parent_order_id on orders whose parent really is an OTO order.
- Use cache persistence so contingent chains survive restarts.
- Reject inbound orders with unresolvable parent_order_id at the client boundary.
When it happens
Trigger: Submitting or validating an order carrying parent_order_id where order_snapshot(parent_order_id) returns None or a parent whose contingency_type != ContingencyType::Oto, with config.support_contingent_orders enabled.
Common situations: Resubmitting/repairing an OTO child order after the parent was purged from the cache; manually constructing an order with parent_order_id set to an unrelated order; mixing contingently-linked order state across node restarts with a non-persistent cache.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- Cannot find contingent order for {client_order_id}
- Order {client_order_id} not found in cache.
- Matching engine not found for instrument {order_instrument_i
- Matching engine not found for instrument {instrument_id}
- Position id should be generated. Hedging Oms type order matc
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/945069aa7288ca66.
Report an issue: GitHub.