QuantConnect/Lean · error · AssertionError
Field self.ticket not expected no be assigned on the first o
Error message
Field self.ticket not expected no be assigned on the first order event
What it means
This assertion encodes the async-ordering invariant the demo teaches: the first OrderEvent (status SUBMITTED) for an asynchronous market order can fire before the self.ticket = self.market_order(...) assignment completes in the consolidator thread. Therefore, at the moment a SUBMITTED event is processed, self.ticket should still be None. If self.ticket is already assigned when the SUBMITTED event arrives, the async ordering the demo relies on has changed (e.g. the assignment now completes synchronously before the event is dispatched).
Source
Thrown at Algorithm.Python/OrderTicketAssignmentDemoAlgorithm.py:46
self.trade_count = 0
self.consolidate(self._symbol, timedelta(hours=1), self.hour_consolidator)
def hour_consolidator(self, bar: TradeBar):
# Reset self.ticket to None on each new bar
self.ticket = None
self.ticket = self.market_order(self._symbol, 1, asynchronous=True)
self.debug(f"{self.time}: Buy: Price {bar.price}, order_id: {self.ticket.order_id}")
self.trade_count += 1
def on_order_event(self, order_event: OrderEvent):
# We cannot access self.ticket directly because it is assigned asynchronously:
# this order event could be triggered before self.ticket is assigned.
ticket = order_event.ticket
if ticket is None:
raise AssertionError("Expected order ticket in order event to not be null")
if order_event.status == OrderStatus.SUBMITTED and self.ticket is not None:
raise AssertionError("Field self.ticket not expected no be assigned on the first order event")
self.debug(ticket.to_string())
def on_end_of_algorithm(self):
# Just checking that orders were placed
if not self.portfolio.invested or self.trade_count != self.transactions.orders_count:
raise AssertionError(f"Expected the portfolio to have holdings and to have {self.trade_count} trades, but had {self.transactions.orders_count}")
View on GitHub (pinned to d2c3659f87)
Solutions
- If the engine legitimately now assigns the ticket before the SUBMITTED event, update the demo's invariant (this assertion may be obsolete).
- Keep relying on order_event.ticket (not self.ticket) inside on_order_event to avoid the race entirely.
- Confirm asynchronous=True still defers ticket assignment; if behavior changed, document the new contract.
- Move the self.ticket assignment off the hot path or use a queue so the ordering remains as the demo intends.
Example fix
# before: assumes self.ticket is None during the SUBMITTED event
if order_event.status == OrderStatus.SUBMITTED and self.ticket is not None:
raise AssertionError(...)
# after: rely on the event's own ticket, not the race-dependent self.ticket
ticket = order_event.ticket
if ticket is None:
raise AssertionError('event ticket should be populated') Defensive patterns
Strategy: validation
Validate before calling
# Do not depend on the race; use the event's own ticket
if order_event.status == OrderStatus.SUBMITTED:
# self.ticket may or may not be assigned yet; that is fine
ticket = order_event.ticket
if ticket is None:
raise AssertionError('event ticket should be populated') Prevention
- Never read a shared self.ticket inside on_order_event for async orders; use order_event.ticket.
- If the engine's async semantics change, update the demo invariant rather than relying on a race.
- Document whether SUBMITTED events precede or follow ticket assignment.
When it happens
Trigger: on_order_event receives an event with order_event.status == OrderStatus.SUBMITTED while self.ticket is not None. Triggered when the market_order(...) return assignment completes before the SUBMITTED event is delivered, breaking the demo's assumed race window.
Common situations: A Lean change making asynchronous order submission/ticket assignment synchronous; threading/event-dispatch changes so the consolidator thread finishes assigning self.ticket before the event handler runs; running in a single-threaded scheduler where the race never occurs.
Related errors
- Expected order ticket in order event to not be null
- Expected the portfolio to have holdings and to have {self.tr
- OrderEvent quantity is Not expected to be 0, it should hold
- OrderEvent quantity should hold the current order Quantity
- OrderEvent Ticket was not set
AI-assisted analysis of QuantConnect/Lean@d2c3659f87 (2026-08-13).
Data as JSON: /api/errors/df2e23c5446ae87e.
Report an issue: GitHub.