QuantConnect/Lean · error · AssertionError
Expected {expected_chain_count} options in chain on {date},
Error message
Expected {expected_chain_count} options in chain on {date}, but got {actual_chain_count} What it means
For each date level in the history DataFrame, the regression compares the number of contracts returned by history (actual_chain_count) against the count from option_chain_provider.get_option_contract_list(option, date) (expected_chain_count). A mismatch means the OptionUniverse history provider and the option chain provider disagree on the universe for that date — a consistency bug in Lean's option universe generation/caching.
Source
Thrown at Algorithm.Python/OptionUniverseHistoryRegressionAlgorithm.py:42
self.set_end_date(2015, 12, 25)
option = self.add_option("GOOG").symbol
historical_options_data_df = self.history(option, 3, flatten=True)
# Level 0 of the multi-index is the date, we expect 3 dates, 3 option chains
if historical_options_data_df.index.levshape[0] != 3:
raise AssertionError(f"Expected 3 option chains from history request, but got {historical_options_data_df.index.levshape[1]}")
for date in historical_options_data_df.index.levels[0]:
expected_chain = list(self.option_chain_provider.get_option_contract_list(option, date))
expected_chain_count = len(expected_chain)
actual_chain = historical_options_data_df.loc[date]
actual_chain_count = len(actual_chain)
if expected_chain_count != actual_chain_count:
raise AssertionError(f"Expected {expected_chain_count} options in chain on {date}, but got {actual_chain_count}")
for i, symbol in enumerate(actual_chain.index):
expected_symbol = expected_chain[i]
if symbol != expected_symbol:
raise AssertionError(f"Expected symbol {expected_symbol} at index {i} on {date}, but got {symbol}")
View on GitHub (pinned to d2c3659f87)
Solutions
- Diff the OptionUniverse history provider and the option_chain_provider code paths to ensure they enumerate the same contracts.
- Re-generate or re-download the option universe data so both providers read identical rows.
- Log both lists for the failing date to see which contracts differ.
- Verify no implicit filter (e.g. strikes/expiry window) is applied in one path but not the other.
Example fix
# diagnostic: log the divergence before asserting
missing = set(map(str, expected_chain)) - set(map(str, actual_chain.index))
extra = set(map(str, actual_chain.index)) - set(map(str, expected_chain))
self.log(f'date={date} missing={missing} extra={extra}')
if expected_chain_count != actual_chain_count:
raise AssertionError(...) Defensive patterns
Strategy: validation
Validate before calling
# Compare counts and log divergence before asserting
expected_chain = list(self.option_chain_provider.get_option_contract_list(option, date))
actual_chain = self.history(option, 3, flatten=True).loc[date]
if len(expected_chain) != len(actual_chain):
self.log(f'date={date} provider={len(expected_chain)} history={len(actual_chain)}')
raise AssertionError('chain count mismatch') Prevention
- Keep the history provider and chain provider enumeration logic consistent in Lean.
- Re-generate option universe data so both providers read identical rows.
- Log both lists for the failing date to localize the divergence.
- Ensure no implicit filter is applied in one path only.
When it happens
Trigger: len(historical_options_data_df.loc[date]) != len(option_chain_provider.get_option_contract_list(option, date)) for some date in the history window. Triggered by a change in how the history provider vs the chain provider enumerate/filter the option universe, or by data version skew between the two code paths.
Common situations: Refactoring option universe generation so history and chain provider use different filtering; a caching stale-data issue; a data package where the two providers read different files for the same date.
Related errors
- Expected 3 option chains from history request, but got {hist
- Expected symbol {expected_symbol} at index {i} on {date}, bu
- Unexpected history count: {history.Count}
- Unexpected history data start time
- Unexpected history data end time
AI-assisted analysis of QuantConnect/Lean@d2c3659f87 (2026-08-13).
Data as JSON: /api/errors/0d048910c24bb4ab.
Report an issue: GitHub.