QuantConnect/Lean · error · RegressionTestException
{Time} unexpected symbol changed event {changedEvent}!
Error message
{Time} unexpected symbol changed event {changedEvent}! What it means
This futures regression algorithm asserts that continuous-contract SymbolChangedEvents (rollovers) only occur at midnight (Time.TimeOfDay == TimeSpan.Zero), i.e. at the daily session boundary. A symbol-change event at any other intraday time is unexpected and indicates mapping fired at the wrong point in the trading day.
Source
Thrown at Algorithm.CSharp/BasicTemplateFuturesAlgorithm.cs:82
var benchmark = AddEquity("SPY");
SetBenchmark(benchmark.Symbol);
var seeder = new FuncSecuritySeeder(GetLastKnownPrices);
SetSecurityInitializer(security => seeder.SeedSecurity(security));
}
/// <summary>
/// Event - v3.0 DATA EVENT HANDLER: (Pattern) Basic template for user to override for receiving all subscription data in a single event
/// </summary>
/// <param name="slice">The current slice of data keyed by symbol string</param>
public override void OnData(Slice slice)
{
foreach (var changedEvent in slice.SymbolChangedEvents.Values)
{
Debug($"{Time} - SymbolChanged event: {changedEvent}");
if (Time.TimeOfDay != TimeSpan.Zero)
{
throw new RegressionTestException($"{Time} unexpected symbol changed event {changedEvent}!");
}
}
if (!Portfolio.Invested)
{
foreach(var chain in slice.FutureChains)
{
// find the front contract expiring no earlier than in 90 days
var contract = (
from futuresContract in chain.Value.OrderBy(x => x.Expiry)
where futuresContract.Expiry > Time.Date.AddDays(90)
select futuresContract
).FirstOrDefault();
// if found, trade it
if (contract != null)
{
_contractSymbol = contract.Symbol;View on GitHub (pinned to d2c3659f87)
Solutions
- Confirm the continuous contract's DataMappingMode maps at the daily boundary consistent with the data set.
- Verify the backtest resolution and session-clock alignment so Time reflects the correct boundary.
- If your data legitimately rolls intraday (e.g. a custom feed), relax the midnight assertion to your expected rollover time.
- Ensure the futures chain data is complete so Lean does not fall back to an alternate rollover instant.
Example fix
// before
if (Time.TimeOfDay != TimeSpan.Zero) { throw ...; }
// after: assert rollover only at the configured mapping time
if (Time.TimeOfDay != ExpectedRolloverTime) { throw ...; } Defensive patterns
Strategy: validation
Validate before calling
foreach (var changedEvent in slice.SymbolChangedEvents.Values)
{
if (Time.TimeOfDay != TimeSpan.Zero)
{
Log($"{Time} - Off-boundary rollover: {changedEvent}. Verify mapping mode/feed.");
}
} Prevention
- Use a DataMappingMode that maps at the daily boundary.
- Confirm resolution and session-clock alignment.
- Pin Lean version so rollover timing is deterministic.
When it happens
Trigger: A SymbolChangedEvent arrives in OnData while Time.TimeOfDay != TimeSpan.Zero — Lean remapped the continuous contract mid-session instead of at the midnight/day boundary.
Common situations: DataMappingMode or contract rollover timing changed in the engine; intraday data triggered an early remap; the data feed's contract chain shifted mid-day; a version change altered when mapping events are emitted relative to the session clock.
Related errors
- {Time} unexpected symbol changed event {changedEvent}!
- {Time} unexpected symbol changed event {changedEvent}!
- {Time} - Unexpected symbol changed event old symbol: {change
- {Time} - Unexpected symbol changed event new symbol: {change
- Unexpected number of symbol changed events (mappings): {_map
AI-assisted analysis of QuantConnect/Lean@d2c3659f87 (2026-08-13).
Data as JSON: /api/errors/f9ad97cbd199e41a.
Report an issue: GitHub.