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

  1. If the engine legitimately now assigns the ticket before the SUBMITTED event, update the demo's invariant (this assertion may be obsolete).
  2. Keep relying on order_event.ticket (not self.ticket) inside on_order_event to avoid the race entirely.
  3. Confirm asynchronous=True still defers ticket assignment; if behavior changed, document the new contract.
  4. 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

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


AI-assisted analysis of QuantConnect/Lean@d2c3659f87 (2026-08-13). Data as JSON: /api/errors/df2e23c5446ae87e. Report an issue: GitHub.