nautechsystems/nautilus_trader · error · anyhow::Error
Existing {existing_venue_order_id} for {client_order_id}
Error message
Existing {existing_venue_order_id} for {client_order_id}
did not match the given {venue_order_id}.
If you are writing a test then try a different `venue_order_id`,
otherwise this is probably a bug. What it means
When adding a venue order ID for a client order ID, the cache already has a different venue order ID mapped and `overwrite` is false. The cache treats a client_order_id -> venue_order_id mapping as immutable unless explicitly overwritten, so a mismatch is rejected as a likely bug or test artifact.
Source
Thrown at crates/common/src/cache/mod.rs:4656
.entry(*client_order_id)
.or_insert(*venue_order_id);
Ok(())
}
fn validate_venue_order_id_claim(
&self,
client_order_id: &ClientOrderId,
venue_order_id: &VenueOrderId,
overwrite: bool,
) -> anyhow::Result<()> {
self.validate_venue_order_id_ownership(client_order_id, venue_order_id)?;
if let Some(existing_venue_order_id) = self.index.client_order_ids.get(client_order_id)
&& !overwrite
&& existing_venue_order_id != venue_order_id
{
anyhow::bail!(
"Existing {existing_venue_order_id} for {client_order_id}
did not match the given {venue_order_id}.
If you are writing a test then try a different `venue_order_id`,
otherwise this is probably a bug."
);
}
Ok(())
}
fn validate_venue_order_id_ownership(
&self,
client_order_id: &ClientOrderId,
venue_order_id: &VenueOrderId,
) -> anyhow::Result<()> {
if let Some(existing_client_order_id) = self.index.venue_order_ids.get(venue_order_id)
&& existing_client_order_id != client_order_id
{View on GitHub (pinned to 18893faf8b)
Solutions
- Pass `overwrite: true` if the venue legitimately reassigned the order ID.
- In tests, use a unique venue_order_id per client_order_id (as the message suggests).
- Verify which venue_order_id the adapter reports; fix the adapter mapping if it is wrong.
Example fix
// before cache.add_venue_order_id(&client_order_id, venue_order_id, venue_order_id_assigned, false); // after cache.add_venue_order_id(&client_order_id, venue_order_id, venue_order_id_assigned, true); // if reassignment is intended
Defensive patterns
Strategy: try-catch
Validate before calling
if let Some(existing) = cache.venue_order_id(&client_order_id) {
if existing != venue_order_id && !overwrite { /* handle mismatch before calling */ }
} Try / catch
match cache.add_venue_order_id(&client_order_id, venue_order_id, ts, overwrite) {
Ok(()) => {},
Err(e) if e.to_string().contains("did not match the given") => {
// retry with overwrite=true or fix the venue_order_id
},
Err(e) => return Err(e),
} Prevention
- Use unique client_order_id/venue_order_id pairs per test case.
- Treat client_order_id -> venue_order_id mapping as immutable; use overwrite only for genuine venue reassignment.
- Log both IDs on every order-report event.
When it happens
Trigger: Calling `add_venue_order_id` (or `update_venue_order_id` with overwrite=false) for a client_order_id that already maps to another venue_order_id; reusing a client_order_id across tests or order generations; venue assign/re-assign flows that pass overwrite=false.
Common situations: Test code reusing fixture client order IDs while generating sequential venue order IDs; sim replay of fills with a stale venue order ID; adapter emitting a different venue order ID for the same client order after amend.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 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/ebb20d65c187d0b4.
Report an issue: GitHub.