QuantConnect/Lean · error · RegressionTestException

Unexpected cancel pending event: {orderEvent}

Error message

Unexpected cancel pending event: {orderEvent}

What it means

When an OrderEvent with Status == CancelPending arrives, all prior steps must be complete: _optionSold, _optionAssigned, _stockAssigned, and _optionDelistedWarningReceived. The delisting warning triggers the cancel of the open LimitOrder, so a CancelPending before these flags are set indicates an out-of-order event sequence.

Source

Thrown at Algorithm.CSharp/DuplicateOptionAssignmentRegressionAlgorithm.cs:111

                {
                    if (orderEvent.Ticket.OrderType != OrderType.OptionExercise || orderEvent.IsAssignment || orderEvent.Symbol != _stock)
                    {
                        throw new RegressionTestException($"Expected stock assignment but got: {orderEvent}");
                    }

                    _stockAssigned = true;
                }
                else
                {
                    throw new RegressionTestException($"Unexpected order fill event: {orderEvent}");
                }
            }
            else if (orderEvent.Status == OrderStatus.CancelPending)
            {
                // We receive the delisting warning before the order cancel is requested
                if (!_optionSold || !_optionAssigned || !_stockAssigned || !_optionDelistedWarningReceived)
                {
                    throw new RegressionTestException($"Unexpected cancel pending event: {orderEvent}");
                }
            }
            else if (orderEvent.Status == OrderStatus.Canceled)
            {
                // The delisted event is received before the order is canceled
                if (!_optionSold || !_optionAssigned || !_stockAssigned || !_optionDelistedWarningReceived || !_optionDelisted)
                {
                    throw new RegressionTestException($"Unexpected cancel event: {orderEvent}");
                }

                _orderCanceled = true;
            }
        }

        public override void OnDelistings(Delistings delistings)
        {
            if (!delistings.TryGetValue(_option, out var delisting))
            {

View on GitHub (pinned to d2c3659f87)

Solutions

  1. Log the full event sequence (all OrderEvents and Delistings in order) to identify which flag is false when CancelPending arrives.
  2. Verify the delisting warning fires before the order cancel is requested.
  3. Check for a Lean regression in delisting-driven order cancellation ordering.
  4. If the sequence legitimately changed, update the flag-gating to match the new flow.
Defensive patterns

Strategy: validation

Validate before calling

else if (orderEvent.Status == OrderStatus.CancelPending)
{
    var ready = _optionSold && _optionAssigned && _stockAssigned && _optionDelistedWarningReceived;
    if (!ready)
    {
        Debug($"CancelPending before sequence complete: sold={_optionSold} optAssign={_optionAssigned} stockAssign={_stockAssigned} warn={_optionDelistedWarningReceived}");
        throw new RegressionTestException($"Unexpected cancel pending event: {orderEvent}");
    }
}

Prevention

When it happens

Trigger: The cancel-pending event arrives before the option was assigned or before the delisting warning — e.g., the order is canceled for a different reason (margin call, manual cancel, delisting without warning), or events arrive out of order.

Common situations: A Lean change in order-cancellation timing during delisting, the LimitOrder being canceled before assignment completes, or a delisting flow that skips the warning step.

Related errors


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