{"record":{"id":"ba52cf591126ffc7","repo":"QuantConnect/Lean","slug":"orderevent-order-id-and-order-event-ticket-order-i","errorCode":null,"errorMessage":"OrderEvent.ORDER_ID and order_event.ticket.order_id do not match","messagePattern":"OrderEvent\\.ORDER_ID and order_event\\.ticket\\.order_id do not match","errorType":"exception","errorClass":"AssertionError","httpStatus":null,"severity":"error","filePath":"Algorithm.Python/OrderTicketDemoAlgorithm.py","lineNumber":408,"sourceCode":"\n        if order_event.quantity == 0:\n            raise AssertionError(\"OrderEvent quantity is Not expected to be 0, it should hold the current order Quantity\")\n\n        if order_event.quantity != order.quantity:\n            raise AssertionError(\"OrderEvent quantity should hold the current order Quantity\")\n\n        if (type(order) is LimitOrder and order_event.limit_price == 0 or\n            type(order) is StopLimitOrder and order_event.limit_price == 0):\n            raise AssertionError(\"OrderEvent LimitPrice is Not expected to be 0 for LimitOrder and StopLimitOrder\")\n\n        if type(order) is StopMarketOrder and order_event.stop_price == 0:\n            raise AssertionError(\"OrderEvent StopPrice is Not expected to be 0 for StopMarketOrder\")\n\n        # We can access the order ticket from the order event\n        if order_event.ticket is None:\n            raise AssertionError(\"OrderEvent Ticket was not set\")\n        if order_event.order_id != order_event.ticket.order_id:\n            raise AssertionError(\"OrderEvent.ORDER_ID and order_event.ticket.order_id do not match\")\n\n    def check_pair_orders_for_fills(self, long_order, short_order):\n        if long_order.status == OrderStatus.FILLED:\n            self.log(\"{0}: Cancelling short order, long order is filled.\".format(short_order.order_type))\n            short_order.cancel(\"Long filled.\")\n            return True\n\n        if short_order.status == OrderStatus.FILLED:\n            self.log(\"{0}: Cancelling long order, short order is filled.\".format(long_order.order_type))\n            long_order.cancel(\"Short filled\")\n            return True\n\n        return False\n\n\n    def time_is(self, day, hour, minute):\n        return self.time.day == day and self.time.hour == hour and self.time.minute == minute\n","sourceCodeStart":390,"sourceCodeEnd":426,"githubUrl":"https://github.com/QuantConnect/Lean/blob/d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892/Algorithm.Python/OrderTicketDemoAlgorithm.py#L390-L426","documentation":"Self-test assertion verifying internal consistency: the OrderId on the OrderEvent must equal the OrderId on the OrderTicket referenced by that same event. Both should identify the same order, since the ticket is the handle created for the order and the event describes a state change of that order. The assertion fires when the two ids disagree.","triggerScenarios":"order_event.order_id != order_event.ticket.order_id, i.e. the ticket attached to the event belongs to a different order than the event itself. This is an integrity violation that can arise if the transaction processor attaches the wrong ticket to an event (a lookup-by-index bug), if an event is cloned/reused across orders, or if the ticket was manually assigned.","commonSituations":"Lean contributors hit this after changing how the transaction manager maps order ids to tickets. Users hit it when they construct or mutate OrderEvent/OrderTicket objects manually, or when a brokerage integration reports events against the wrong internal order id. Rare in normal use; indicates a real data-integrity bug when seen.","solutions":["As an engine regression: inspect the transaction manager's ticket lookup to confirm it keys tickets by the same OrderId used to build the event.","If you build/reassign tickets manually: never attach a ticket from one order to an event of another; create the ticket from the order being submitted.","In a custom handler: cross-check using self.transactions.get_order_by_id(order_event.order_id) and report the mismatch rather than asserting, if full integrity is not guaranteed.","For cloned events: use OrderEvent.Clone() and never reassign OrderId without also re-resolving the ticket."],"exampleFix":"# before\nif order_event.order_id != order_event.ticket.order_id:\n    raise AssertionError(\"OrderEvent.ORDER_ID and order_event.ticket.order_id do not match\")\n\n# after (fail with enough context to diagnose the mismatch)\nif order_event.order_id != order_event.ticket.order_id:\n    raise AssertionError(\n        f\"OrderEvent id {order_event.order_id} does not match \"\n        f\"ticket id {order_event.ticket.order_id} for symbol {order_event.symbol}\")","handlingStrategy":"validation","validationCode":"# Validate id consistency before using the ticket\nticket = order_event.ticket\nif ticket is None or order_event.order_id != ticket.order_id:\n    self.debug(f\"Event/ticket id mismatch for order {order_event.order_id}\")\n    # fall back to a fresh lookup by the event's authoritative order id\n    order = self.transactions.get_order_by_id(order_event.order_id)\n    # proceed using `order`, not the mismatched ticket","typeGuard":"def event_ticket_ids_match(order_event):\n    \"\"\"True when the event carries a ticket whose order id equals the event's order id.\"\"\"\n    return (order_event.ticket is not None\n            and order_event.order_id == order_event.ticket.order_id)","tryCatchPattern":null,"preventionTips":["Use order_event.order_id as the source of truth; treat the ticket as a convenience reference.","Never reassign an OrderId without re-resolving the associated ticket.","Clone events with OrderEvent.Clone() rather than hand-copying fields."],"tags":["quantconnect","lean","orders","order-event","order-ticket","data-integrity","regression-test","python"],"backgroundTag":null,"analyzedSha":"d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892","analyzedAt":"2026-08-13T13:52:21.013Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}