dotnet/efcore · error · InvalidOperationException

Couldn't get interceptable location for

Error message

Couldn't get interceptable location for: '{node}'.

What it means

Thrown by the precompiled-query code generator when Roslyn's SemanticModel.GetInterceptableLocation returns null for a LINQ operator invocation. Precompiled queries depend on the [InterceptsLocation] feature, which requires the compiler to be able to attribute a precise source location for interception; if it cannot, generation cannot proceed and throws InvalidOperationException.

Solutions

  1. Upgrade the .NET SDK to a version that supports [InterceptsLocation] (preview precompiled-query requirement).
  2. Ensure the project targets a compatible TFM for precompiled queries.
  3. Disable precompiled queries for the affected query or project until the toolchain supports interception.
Defensive patterns

Strategy: validation

Validate before calling

// Detect interceptor support before enabling precompiled queries
var sdkSupportsInterceptors = typeof(System.Runtime.CompilerServices.InterceptsLocationAttribute).Assembly.GetType("System.Runtime.CompilerServices.InterceptsLocationAttribute") is not null;
if (!sdkSupportsInterceptors) { /* disable precompiled queries */ }

Try / catch

try { generator.Generate(/*...*/); }
catch (InvalidOperationException ex) when (ex.Message.Contains("interceptable location"))
{ /* fall back to non-precompiled execution, or instruct user to upgrade SDK */ }

Prevention

When it happens

Trigger: Enabling precompiled queries on a project compiled with a Roslyn/.NET SDK version that does not support interceptors, or on an invocation syntax that is not eligible for interception (e.g. certain dynamic or partially-resolved calls).

Common situations: Targeting an older .NET SDK/TFM that lacks interceptor support; using a preview precompiled-query feature with an incompatible toolchain; source-generator ordering issues where the semantic model cannot resolve the invocation.

Related errors


AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11). Data as JSON: /api/errors/fd691a15a403837d. Report an issue: GitHub.

Appendix: source

Thrown at src/EFCore.Design/Query/Internal/PrecompiledQueryCodeGenerator.cs:521

                : returnTypeSymbol;

        var returnElementTypeSymbol = returnTypeWithoutTask switch
        {
            IArrayTypeSymbol arrayTypeSymbol => arrayTypeSymbol.ElementType,
            INamedTypeSymbol namedReturnType2
                when namedReturnType2.AllInterfaces.Prepend(namedReturnType2)
                    .Any(i => i.OriginalDefinition.Equals(_symbols.GenericEnumerable, SymbolEqualityComparer.Default)
                        || i.OriginalDefinition.Equals(_symbols.GenericAsyncEnumerable, SymbolEqualityComparer.Default)
                        || i.OriginalDefinition.Equals(_symbols.GenericEnumerator, SymbolEqualityComparer.Default))
                => namedReturnType2.TypeArguments[0],
            _ => null
        };

        // Output the interceptor method signature preceded by the [InterceptsLocation] attribute.
        var interceptorName = $"Query{queryNum}_{memberAccessSyntax.Name}{operatorNum}";
        var invocationSyntax = (InvocationExpressionSyntax)operatorSyntax;
        var interceptableLocation = semanticModel.GetInterceptableLocation(invocationSyntax, cancellationToken)
            ?? throw new InvalidOperationException(DesignStrings.CouldNotGetInterceptableLocation(operatorSyntax));
        code.AppendLine(interceptableLocation.GetInterceptsLocationAttributeSyntax());
        GenerateInterceptorMethodSignature();
        code.AppendLine("{").IncrementIndent();

        // If this is the first query operator (no nested operator), cast the input source to IInfrastructure<DbContext> and extract the
        // DbContext, create a new QueryContext, and wrap it all in a PrecompiledQueryContext that will flow through to the
        // terminating operator, where the query will actually get executed.
        // Otherwise, if this is a non-first operator, receive the PrecompiledQueryContext from the nested operator and flow it forward.
        code.AppendLine(
            "var precompiledQueryContext = "
            + (operatorNum == 1
                ? $"new PrecompiledQueryContext<{sourceElementTypeName}>(((IInfrastructure<DbContext>){sourceVariableName}).Instance);"
                : $"(PrecompiledQueryContext<{sourceElementTypeName}>){sourceVariableName};"));

        var declaredQueryContextVariable = false;

        ProcessCapturedVariables();

View on GitHub (pinned to 3a2006ef56)