{"record":{"id":"8f18c339fff9a8c4","repo":"QuantConnect/Lean","slug":"expected-at-least-one-option-contract-for","errorCode":null,"errorMessage":"Expected at least one option contract for {}","messagePattern":"Expected at least one option contract for (.+?)","errorType":"exception","errorClass":"RegressionTestException","httpStatus":null,"severity":"error","filePath":"Algorithm.Python/FutureOptionWithFutureFilterRegressionAlgorithm.py","lineNumber":35,"sourceCode":"\n### <summary>\n### Regression algorithm that validates that when using a Future with filter\n### the option chains are correctly populated and are unique\n### </summary>\nclass FutureOptionWithFutureFilterRegressionAlgorithm(FutureOptionContinuousFutureRegressionAlgorithm):\n    def set_filter(self):\n        \"\"\"Set future filter for specific contracts\"\"\"\n        self.future.set_filter(0, 368)\n    \n    def validate_option_chains(self, slice: Slice):\n        future_contracts_with_option_chains = 0\n        for future_chain in slice.future_chains.values():\n            for future_contract in future_chain:\n                # Not all future contracts have option chains, so we need to check if the contract is in the option chain\n                if future_contract.symbol in slice.option_chains:\n                    chain = slice.option_chains[future_contract.symbol]\n                    if len(chain) == 0:\n                        raise RegressionTestException(\"Expected at least one option contract for {}\".format(chain.symbol))\n                    future_contracts_with_option_chains += 1\n        \n        if future_contracts_with_option_chains < 1:\n            raise RegressionTestException(\"Expected at least two future contracts with option chains, but found {}\".format(future_contracts_with_option_chains))","sourceCodeStart":17,"sourceCodeEnd":39,"githubUrl":"https://github.com/QuantConnect/Lean/blob/d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892/Algorithm.Python/FutureOptionWithFutureFilterRegressionAlgorithm.py#L17-L39","documentation":"FutureOptionWithFutureFilterRegressionAlgorithm.validate_option_chains inspects each future contract that has an option chain in the slice and asserts the chain is non-empty. An empty option chain (len(chain) == 0) for a contract that should have options raises RegressionTestException — it signals the option data is missing or the filter excluded everything.","triggerScenarios":"A future_contract.symbol exists in slice.option_chains, but the corresponding OptionChain has zero contracts, so len(chain) == 0 trips the check.","commonSituations":"Option data for that future is missing from the data set, the future filter (set_filter 0–368 days) selected a contract with no listed options, or a data-provider/regional change dropped option chain entries.","solutions":["Verify the test data set includes option chains for every future contract the filter selects.","Tighten set_filter so it only returns futures that actually have listed options.","If running locally, confirm the future-option data files are present and correctly keyed."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"def validate_option_chains(self, slice):\n    for future_contract in (fc for fc_chain in slice.future_chains.values() for fc in fc_chain):\n        chain = slice.option_chains.get(future_contract.symbol)\n        if chain is None:\n            continue  # contract has no option chain — allowed\n        if len(chain) == 0:\n            self.Debug(f'Skipping empty option chain for {chain.symbol}')  # tolerate instead of raising","typeGuard":"def chain_has_contracts(chain) -> bool:\n    return chain is not None and len(chain) > 0","tryCatchPattern":null,"preventionTips":["Constrain set_filter to futures that actually list options.","When running locally, confirm option-chain data files exist for every selected future.","If an empty chain is acceptable for some contracts, skip them rather than asserting non-emptiness."],"tags":["regression-test","future-options","option-chain","data"],"backgroundTag":null,"analyzedSha":"d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892","analyzedAt":"2026-08-13T13:52:21.013Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}