QuantConnect/Lean · error · RegressionTestException

We expected 'SPY' to be added to the Symbol cache, since the

Error message

We expected 'SPY' to be added to the Symbol cache, since the algorithm is also using it

What it means

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.

Source

Thrown at Algorithm.CSharp/CustomUniverseWithBenchmarkRegressionAlgorithm.cs:69

                {
                    if(x.Day % 2 == 0)
                    {
                        _universeSelected = true;
                        return new List<string> {"SPY"};
                    }
                    _universeSelected = false;
                    return Enumerable.Empty<string>();
                }
            );

            // internal daily resolution
            SetBenchmark("SPY");

            Symbol symbol;
            if (!SymbolCache.TryGetSymbol("SPY", out symbol)
                || !ReferenceEquals(_spy, symbol))
            {
                throw new RegressionTestException("We expected 'SPY' to be added to the Symbol cache," +
                                    " since the algorithm is also using it");
            }
        }

        /// <summary>
        /// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
        /// </summary>
        /// <param name="slice">Slice object keyed by symbol containing the stock data</param>
        public override void OnData(Slice slice)
        {
            var security = Securities[_spy];
            _onDataWasCalled = true;

            var bar = slice.Bars.Values.Single();
            if (_universeSelected)
            {
                if (bar.IsFillForward
                    || bar.Period != TimeSpan.FromMinutes(1))

View on GitHub (pinned to d2c3659f87)

Solutions

  1. Check SymbolCache.TryGetSymbol return value independently — if false, the cache was never populated for SPY.
  2. If the symbol exists but isn't reference-equal, trace whether SetBenchmark and AddEquity go through the same Symbol resolution path.
  3. Verify that SymbolCache.Set/Get logic deduplicates by ticker+market+securityType, not by creating new instances.
  4. If testing engine changes, ensure the benchmark subscription reuses the existing Security from Securities rather than creating a new one.

Example fix

// before — fails if SymbolCache creates separate instances
_spy = AddEquity("SPY", Resolution.Hour).Symbol;
SetBenchmark("SPY");
Symbol symbol;
if (!SymbolCache.TryGetSymbol("SPY", out symbol) || !ReferenceEquals(_spy, symbol))
    throw new RegressionTestException("...");

// after — engine-side fix: ensure SetBenchmark resolves through SymbolCache
// In the benchmark/security manager:
Symbol symbol = SymbolCache.TryGetSymbol(ticker, out var existing) ? existing : Symbol.Create(ticker, SecurityType.Equity, Market.USA);
SymbolCache.Set(ticker, symbol);
Defensive patterns

Strategy: validation

Validate before calling

// Validate SymbolCache after AddEquity and SetBenchmark
_spy = AddEquity("SPY", Resolution.Hour).Symbol;
SetBenchmark("SPY");
if (!SymbolCache.TryGetSymbol("SPY", out var cached) || !ReferenceEquals(_spy, cached))
    Log("SymbolCache does not share the SPY instance — investigating...");

Type guard

bool IsSymbolCached(string ticker, Symbol expected)
{
    return SymbolCache.TryGetSymbol(ticker, out var cached) && ReferenceEquals(expected, cached);
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of QuantConnect/Lean@d2c3659f87 (2026-08-13). Data as JSON: /api/errors/bf1459e3746dcea9. Report an issue: GitHub.