{"record":{"id":"bf1459e3746dcea9","repo":"QuantConnect/Lean","slug":"we-expected-spy-to-be-added-to-the-symbol-cache","errorCode":null,"errorMessage":"We expected 'SPY' to be added to the Symbol cache, since the algorithm is also using it","messagePattern":"We expected 'SPY' to be added to the Symbol cache, since the algorithm is also using it","errorType":"exception","errorClass":"RegressionTestException","httpStatus":null,"severity":"error","filePath":"Algorithm.CSharp/CustomUniverseWithBenchmarkRegressionAlgorithm.cs","lineNumber":69,"sourceCode":"                {\n                    if(x.Day % 2 == 0)\n                    {\n                        _universeSelected = true;\n                        return new List<string> {\"SPY\"};\n                    }\n                    _universeSelected = false;\n                    return Enumerable.Empty<string>();\n                }\n            );\n\n            // internal daily resolution\n            SetBenchmark(\"SPY\");\n\n            Symbol symbol;\n            if (!SymbolCache.TryGetSymbol(\"SPY\", out symbol)\n                || !ReferenceEquals(_spy, symbol))\n            {\n                throw new RegressionTestException(\"We expected 'SPY' to be added to the Symbol cache,\" +\n                                    \" since the algorithm is also using it\");\n            }\n        }\n\n        /// <summary>\n        /// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.\n        /// </summary>\n        /// <param name=\"slice\">Slice object keyed by symbol containing the stock data</param>\n        public override void OnData(Slice slice)\n        {\n            var security = Securities[_spy];\n            _onDataWasCalled = true;\n\n            var bar = slice.Bars.Values.Single();\n            if (_universeSelected)\n            {\n                if (bar.IsFillForward\n                    || bar.Period != TimeSpan.FromMinutes(1))","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/QuantConnect/Lean/blob/d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892/Algorithm.CSharp/CustomUniverseWithBenchmarkRegressionAlgorithm.cs#L51-L87","documentation":"This RegressionTestException is thrown in Initialize after AddEquity(\"SPY\", Hour) and SetBenchmark(\"SPY\"). It asserts that SPY exists in the SymbolCache and that the cached Symbol is reference-equal to the one returned by AddEquity. LEAN throws it to verify that when a benchmark security shares a ticker with an algorithm security, the SymbolCache deduplicates them to the same Symbol instance.","triggerScenarios":"SymbolCache.TryGetSymbol(\"SPY\") returns false (SPY was never added to the cache), or it returns a different Symbol instance than _spy. The latter happens when AddEquity and SetBenchmark create separate Symbol objects for the same ticker instead of resolving to a shared one.","commonSituations":"A LEAN version change refactored SymbolCache population logic so benchmark securities no longer share Symbol instances with algorithm securities. Also occurs when Symbol creation or resolution logic changed to produce non-deduplicated instances for the same ticker-market-type triplet.","solutions":["Check SymbolCache.TryGetSymbol return value independently — if false, the cache was never populated for SPY.","If the symbol exists but isn't reference-equal, trace whether SetBenchmark and AddEquity go through the same Symbol resolution path.","Verify that SymbolCache.Set/Get logic deduplicates by ticker+market+securityType, not by creating new instances.","If testing engine changes, ensure the benchmark subscription reuses the existing Security from Securities rather than creating a new one."],"exampleFix":"// before — fails if SymbolCache creates separate instances\n_spy = AddEquity(\"SPY\", Resolution.Hour).Symbol;\nSetBenchmark(\"SPY\");\nSymbol symbol;\nif (!SymbolCache.TryGetSymbol(\"SPY\", out symbol) || !ReferenceEquals(_spy, symbol))\n    throw new RegressionTestException(\"...\");\n\n// after — engine-side fix: ensure SetBenchmark resolves through SymbolCache\n// In the benchmark/security manager:\nSymbol symbol = SymbolCache.TryGetSymbol(ticker, out var existing) ? existing : Symbol.Create(ticker, SecurityType.Equity, Market.USA);\nSymbolCache.Set(ticker, symbol);","handlingStrategy":"validation","validationCode":"// Validate SymbolCache after AddEquity and SetBenchmark\n_spy = AddEquity(\"SPY\", Resolution.Hour).Symbol;\nSetBenchmark(\"SPY\");\nif (!SymbolCache.TryGetSymbol(\"SPY\", out var cached) || !ReferenceEquals(_spy, cached))\n    Log(\"SymbolCache does not share the SPY instance — investigating...\");","typeGuard":"bool IsSymbolCached(string ticker, Symbol expected)\n{\n    return SymbolCache.TryGetSymbol(ticker, out var cached) && ReferenceEquals(expected, cached);\n}","tryCatchPattern":null,"preventionTips":["Call AddEquity before SetBenchmark so the security exists when the benchmark resolves the ticker.","Understand that SymbolCache deduplicates by ticker — verify the engine reuses the same instance.","If working on engine internals, ensure benchmark creation doesn't instantiate a separate Security."],"tags":["quantconnect","lean","symbol-cache","benchmark","reference-equality","regression-test"],"backgroundTag":null,"analyzedSha":"d2c3659f877bfc2b5d9dc0fc89a9c7566f45e892","analyzedAt":"2026-08-13T13:52:21.013Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}