{"record":{"id":"f4ead13739c5b565","repo":"QuantConnect/Lean","slug":"expected-symbols-were-not-added-to-the-algorithm","errorCode":null,"errorMessage":"Expected symbols were not added to the algorithm","messagePattern":"Expected symbols were not added to the algorithm","errorType":"exception","errorClass":"RegressionTestException","httpStatus":null,"severity":"error","filePath":"Algorithm.CSharp/CustomUniverseImmediateSelectionRegressionAlgorithm.cs","lineNumber":98,"sourceCode":"            }\n\n            if (!_securitiesChanged)\n            {\n                // Selection should be happening right on algorithm start\n                if (Time != StartDate)\n                {\n                    throw new RegressionTestException(\"Universe selection should have been triggered right away\");\n                }\n\n                if (changes.AddedSecurities.Count != ExpectedSymbols.Count)\n                {\n                    throw new RegressionTestException($\"Expected {ExpectedSymbols.Count} stocks to be added to the algorithm, \" +\n                        $\"but found {changes.AddedSecurities.Count}\");\n                }\n\n                if (!ExpectedSymbols.All(x => changes.AddedSecurities.Any(security => security.Symbol == x)))\n                {\n                    throw new RegressionTestException(\"Expected symbols were not added to the algorithm\");\n                }\n\n                _securitiesChanged = true;\n            }\n        }\n\n        public override void OnEndOfAlgorithm()\n        {\n            if (_firstOnData || !_selected || !_securitiesChanged)\n            {\n                throw new RegressionTestException(\"Expected events didn't happen\");\n            }\n        }\n\n        /// <summary>\n        /// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm.\n        /// </summary>\n        public bool CanRunLocally { get; } = true;","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/QuantConnect/Lean/blob/d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892/Algorithm.CSharp/CustomUniverseImmediateSelectionRegressionAlgorithm.cs#L80-L116","documentation":"This RegressionTestException is thrown in OnSecuritiesChanged after the AddedSecurities count check passes. It asserts that every symbol in ExpectedSymbols is present in changes.AddedSecurities by value equality. LEAN uses it to verify the universe selector produced not just the right *count* of securities but the correct *identities* — symbol, security type, and market must all match.","triggerScenarios":"The AddedSecurities count equals ExpectedSymbols.Count (3) but the actual symbols differ — e.g. the selector returned different tickers than expected, or the engine resolved tickers to symbols with a different SecurityType or Market than ExpectedSymbols specifies. Also fires if Symbol equality semantics changed (SID vs ticker-based).","commonSituations":"Selector function logic changed to return different tickers under some conditions, symbol resolution maps a ticker to a different market (e.g. Market.USA vs Market.OANDA), or a LEAN upgrade changed Symbol equality or SymbolCache behavior.","solutions":["Log both ExpectedSymbols and changes.AddedSecurities to identify which symbol is missing or mismatched.","Confirm the selector function returns the exact same tickers every call (no conditional logic altering the set).","Verify that Symbol.Create in ExpectedSymbols uses the same SecurityType and Market as the AddUniverse call.","If testing engine changes, check that universe-selection output is not reordered or remapped before reaching OnSecuritiesChanged."],"exampleFix":"// before\nprivate static readonly List<Symbol> ExpectedSymbols = new List<Symbol>()\n{\n    Symbol.Create(\"SPY\", SecurityType.Equity, Market.USA),\n    Symbol.Create(\"GOOG\", SecurityType.Equity, Market.USA),\n    Symbol.Create(\"APPL\", SecurityType.Equity, Market.USA)  // wrong\n};\n// selector returns: new[] { \"SPY\", \"GOOG\", \"AAPL\" }\n\n// after — keep ExpectedSymbols in sync with the selector output\nprivate static readonly List<Symbol> ExpectedSymbols = new List<Symbol>()\n{\n    Symbol.Create(\"SPY\", SecurityType.Equity, Market.USA),\n    Symbol.Create(\"GOOG\", SecurityType.Equity, Market.USA),\n    Symbol.Create(\"AAPL\", SecurityType.Equity, Market.USA)\n};","handlingStrategy":"validation","validationCode":"// Validate symbol identity before the assertion\nvar actualSet = changes.AddedSecurities.Select(s => s.Symbol).ToHashSet();\nvar missingSymbols = ExpectedSymbols.Where(s => !actualSet.Contains(s)).ToList();\nif (missingSymbols.Any())\n    Debug($\"Missing symbols: {string.Join(\", \", missingSymbols.Select(s => s.Value))}\");","typeGuard":"bool SymbolsMatch(List<Symbol> expected, IEnumerable<Symbol> actual)\n{\n    var actualSet = actual.ToHashSet();\n    return expected.All(s => actualSet.Contains(s));\n}","tryCatchPattern":null,"preventionTips":["Use Symbol.Create with consistent SecurityType and Market in both ExpectedSymbols and the selector.","Avoid conditional logic in the selector that could return different tickers on different calls.","Unit-test the selector function independently before wiring it to AddUniverse."],"tags":["quantconnect","lean","universe-selection","regression-test","symbols","equality"],"backgroundTag":null,"analyzedSha":"d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892","analyzedAt":"2026-08-13T13:52:21.013Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}