QuantConnect/Lean · error · RegressionTestException
Unexpected delisting events
Error message
Unexpected delisting events
What it means
This assertion sits in OnDelistings of a regression algorithm that sells an option, expects it to be assigned (stock delivered), then expects the option to delist. It enforces that every Delistings collection delivered to the algorithm contains the specific option symbol (_option) the test holds. QuantConnect Lean dispatches a Delistings collection per time step; if delistings.TryGetValue(_option, ...) returns false, the engine sent a delisting for a symbol other than the one the test tracks, which means the delisting pipeline produced an off-target or spurious event.
Source
Thrown at Algorithm.CSharp/DuplicateOptionAssignmentRegressionAlgorithm.cs:130
}
}
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))
{
throw new RegressionTestException($"Unexpected delisting events");
}
if (delisting.Type == DelistingType.Warning)
{
if (!_optionSold || !_optionAssigned || !_stockAssigned || _optionDelistedWarningReceived)
{
throw new RegressionTestException($"Unexpected delisting warning event: {delisting}");
}
_optionDelistedWarningReceived = true;
}
else
{
if (!_optionSold || !_optionAssigned || !_stockAssigned || !_optionDelistedWarningReceived || _optionDelisted)
{
throw new RegressionTestException($"Unexpected delisting event: {delisting}");
}
View on GitHub (pinned to d2c3659f87)
Solutions
- Log every entry in the Delistings collection at the throw site to see which Symbol/Type arrived unexpectedly.
- Trace delisting event generation in Lean (Delisting provider / SecurityManager) for the unexpected symbol and find who created that security.
- If the extra event is expected after your engine change, widen the assertion to allow it; otherwise fix the engine to stop emitting the spurious delisting.
Example fix
// before
if (!delistings.TryGetValue(_option, out var delisting))
{
throw new RegressionTestException($"Unexpected delisting events");
}
// after (diagnostic + tolerant of known extra symbol)
if (!delistings.TryGetValue(_option, out var delisting))
{
throw new RegressionTestException(
$"Unexpected delisting events. Got: {string.Join(", ", delistings.Select(d => $"{d.Symbol}:{d.Type}"))}");
} Defensive patterns
Strategy: validation
Validate before calling
// Validate the delistings collection before asserting on a single symbol
if (delistings == null || !delistings.Any())
{
// no delistings this step; nothing to assert
return;
}
var unexpected = delistings.Where(d => d.Symbol != _option).ToList();
if (unexpected.Count > 0)
{
throw new RegressionTestException(
$"Off-target delisting(s): {string.Join(", ", unexpected.Select(d => $"{d.Symbol}:{d.Type}"))}");
} Try / catch
try { var delisting = delistings[_option]; /* use */ }
catch (KeyNotFoundException) { /* log full collection, then rethrow with context */ } Prevention
- Always log the full Delistings collection contents, not just the expected symbol.
- When adding securities to a regression algorithm, account for every symbol that could delist.
- Guard regression handlers against empty collections before indexing.
When it happens
Trigger: A delisting event arrives whose Symbol != _option (e.g. the underlying stock delists, a second option contract is delisted, or the collection is empty). Triggered by changes to the delisting dispatcher in AlgorithmManager or the delisting event provider emitting for an unexpected canonical/security.
Common situations: Refactoring SecurityService/SubscriptionManager so a duplicate security lingers and delists; introducing a new auxiliary symbol in the test that carries delisting metadata; data-file changes adding delisting info for an extra symbol; an option canonical symbol resolution change.
Related errors
- Unexpected delisting warning event: {delisting}
- Unexpected delisting event: {delisting}
- Option delisting warning was not received
- Option was not delisted
- Unexpected cancel pending event: {orderEvent}
AI-assisted analysis of QuantConnect/Lean@d2c3659f87 (2026-08-13).
Data as JSON: /api/errors/b9f96e2b6d7a3f8a.
Report an issue: GitHub.