nautechsystems/nautilus_trader · error
maker order {} appears more than once in trade {}
Error message
maker order {} appears more than once in trade {} What it means
While rebuilding trades from provider maker-order data, reconciliation asserts that each maker order (by order_id) appears in at most one trade. Seeing the same maker order id in two trades means the provider data is self-contradictory, so the reconciliation fails fast via `anyhow::ensure!` rather than double-counting a fill.
Source
Thrown at crates/adapters/polymarket/src/execution/reconciliation.rs:1171
}
};
let instrument_id = instrument.id();
if scope
.instrument_id
.is_some_and(|requested| instrument_id != requested)
{
continue;
}
if !instrument_in_load_ids_scope(instrument_id, load_ids) {
log::debug!(
"Dropping loaded out-of-scope historical instrument {instrument_id}",
);
continue;
}
anyhow::ensure!(
!selected_maker_orders
.iter()
.any(|(selected, _, _, _)| selected.order_id == mo.order_id),
"maker order {} appears more than once in trade {}",
mo.order_id,
trade.id,
);
let identifiers = validate_maker_report_identifiers(trade, mo)?;
validate_instrument_binding(&instrument, trade.market.as_str(), mo.outcome)?;
validate_maker_order_side(trade, mo)?;
let last_px = validate_trade_values(
mo.matched_amount,
mo.price,
instrument.size_precision(),
&format!("maker order {} matched amount", mo.order_id),
&format!("maker order {} price", mo.order_id),View on GitHub (pinned to 18893faf8b)
Solutions
- Log the offending mo.order_id and the two trade ids, then query the Polymarket Data API directly to determine which trade attribution is correct.
- Deduplicate maker orders by order_id across all fetched trades before reconciliation, dropping later duplicates whose payloads are identical.
- Ensure trade fetches use a consistent snapshot (single request window) so a maker order is not attributed under both a pre- and post-correction record.
- Upgrade the nautilus_polymarket adapter if the venue legitimately reattributes maker orders and newer reconciliation logic handles it.
Example fix
// before: hard failure when a maker order spans two trades
anyhow::ensure!(
!selected_maker_orders.iter().any(|(selected, _, _, _)| selected.order_id == mo.order_id),
"maker order {} appears more than once in trade {}",
mo.order_id,
trade.id,
);
// after: pre-deduplicate maker orders by order_id so each appears once
let mut seen_maker_orders: AHashSet<Uuid> = AHashSet::new();
for mo in maker_orders {
if !seen_maker_orders.insert(mo.order_id) {
log::warn!("Skipping duplicate maker order {}", mo.order_id);
continue;
}
// ... admit maker order
} Defensive patterns
Strategy: validation
Validate before calling
let mut seen: AHashSet<Uuid> = AHashSet::new();
for mo in all_maker_orders() {
if !seen.insert(mo.order_id) {
return Err(anyhow::anyhow!(
"maker order {} pre-attributed to multiple trades; resolve before reconciling",
mo.order_id,
));
}
} Type guard
fn is_unique_maker_order(seen: &mut AHashSet<Uuid>, mo: &PolymarketMakerOrder) -> bool {
seen.insert(mo.order_id)
} Try / catch
match reconciliation_result {
Err(e) if e.to_string().contains("appears more than once in trade") => {
log::warn!("duplicate maker order attribution; re-fetching trades from provider");
retry_with_fresh_snapshot();
}
other => other?,
} Prevention
- Group maker orders into trades once, from one provider snapshot
- Deduplicate maker orders by order_id before trade reconciliation
- Avoid merging trades fetched at different times when venue corrections may have occurred
- Verify ambiguous attributions directly against the Polymarket Data API
When it happens
Trigger: Running Polymarket trade/fill reconciliation (the code path that iterates `selected_maker_orders` for a trade) when the provider response contains the same maker order_id attributed to two distinct trade ids, or duplicated within one trade's maker list.
Common situations: Provider API returning overlapping trade records across paginated queries; venue self-trade or merger of two fills causing one maker order to span records; mixing trades fetched at different times where one was later corrected/merged; buggy local grouping that inserts the same maker order into multiple trade buckets.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- provider trade {} repeats with contradictory evidence
- provider venue order {} repeats with contradictory evidence
- target order {venue_order_id} appears more than once in trad
- trade {} trader_side {:?} contradicts target order {venue_or
- unmapped_in_scope_message("open order", instrument_id, Some(
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/0150284b3240cfb3.
Report an issue: GitHub.