QuantConnect/Lean · error · RegressionTestException
Expected symbol {expected_symbol} at index {i} on {date}, b
Error message
Expected symbol {expected_symbol} at index {i} on {date}, but got {symbol} What it means
Order-sensitive symbol check inside the same FutureUniverse history loop. After counts match, the test walks actual_chain.index position-by-position and compares each Symbol against expected_chain[i]. The first position where they differ aborts.
Source
Thrown at Algorithm.Python/FutureUniverseHistoryRegressionAlgorithm.py:49
if historical_futures_data_df.index.levshape[0] != 3:
raise RegressionTestException(f"Expected 3 futures chains from history request, "
f"but got {historical_futures_data_df.index.levshape[1]}")
for date in historical_futures_data_df.index.levels[0]:
expected_chain = list(self.future_chain_provider.get_future_contract_list(future, date))
expected_chain_count = len(expected_chain)
actual_chain = historical_futures_data_df.loc[date]
actual_chain_count = len(actual_chain)
if expected_chain_count != actual_chain_count:
raise RegressionTestException(f"Expected {expected_chain_count} futures in chain on {date}, "
f"but got {actual_chain_count}")
for i, symbol in enumerate(actual_chain.index):
expected_symbol = expected_chain[i]
if symbol != expected_symbol:
raise RegressionTestException(f"Expected symbol {expected_symbol} at index "
f" {i} on {date}, but got {symbol}")
View on GitHub (pinned to d2c3659f87)
Solutions
- Print expected_chain and list(actual_chain.index) side by side to find the divergent position.
- Confirm both sources sort by the same key (typically expiry then strike).
- Check Symbol equality semantics — compare .underlying / .id rather than the full object if mapping differs.
- If sort order changed intentionally, realign the regression rather than reordering data.
Defensive patterns
Strategy: validation
Validate before calling
# Detect ordering divergence before raising
for date in df.index.levels[0]:
expected = list(self.future_chain_provider.get_future_contract_list(future, date))
actual = list(df.loc[date].index)
for i, (e, a) in enumerate(zip(expected, actual)):
if e != a:
self.debug(f"Symbol order differs at {i} on {date}: expected={e} actual={a}") Type guard
def chains_same_order(provider, future, df) -> bool:
for d in df.index.levels[0]:
exp = list(provider.get_future_contract_list(future, d))
act = list(df.loc[d].index)
if exp != act:
return False
return True Prevention
- Confirm both sources sort contracts by the same key.
- Compare Symbol.id or Symbol.underlying when mapping differs.
- Refresh data if contracts were inserted/removed.
- Log full expected vs actual lists at the first divergence.
When it happens
Trigger: The history result orders contracts differently from future_chain_provider.get_future_contract_list (e.g. by expiry vs by symbol string); a contract added/removed shifting positions; Symbol equality failing due to canonical vs mapped differences.
Common situations: Sort-order changes between engine versions; data refreshes inserting a contract mid-chain; Symbol comparison mismatch when one side is a continuous canonical and the other a mapped contract.
Related errors
- Expected 3 futures chains from history request, but got {his
- Expected {expected_chain_count} futures in chain on {date},
- [{UtcTime}] We hold a delisted securities: {string.Join(",",
- Expected at least two future contracts with option chains, b
- The Exchange hours was closed, verify 'extended_market_hours
AI-assisted analysis of QuantConnect/Lean@d2c3659f87 (2026-08-13).
Data as JSON: /api/errors/ef788fc3aac26662.
Report an issue: GitHub.