dotnet/efcore · error · InvalidOperationException

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

Error message

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

What it means

Thrown in PrecompiledQueryCodeGenerator.GenerateOperatorInterceptor (line 521) when Roslyn's semanticModel.GetInterceptableLocation returns null for the operator's InvocationExpressionSyntax. Precompiled queries rely on the [InterceptsLocation] attribute, which requires a valid interceptable location; without one EF cannot emit the attribute that rewires the call site to the generated interceptor. It is a hard failure of the interceptor mechanism for that call site.

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 dbf9771522)

Solutions

  1. Raise the project's C# language version to one that supports interceptors (set <LangVersion>latest</LangVersion> or the required preview version) and use a compatible SDK.
  2. Move the query so the intercepted operator invocation lives in ordinary, editable user source rather than generated/synthesized code.
  3. Simplify the query to isolate which operator invocation cannot be intercepted and restructure or drop it.
  4. If the location genuinely cannot be intercepted, exclude that query from precompiled-query generation.

Example fix

<!-- before -->
<PropertyGroup>
  <LangVersion>10.0</LangVersion>
</PropertyGroup>

<!-- after -->
<PropertyGroup>
  <LangVersion>latest</LangVersion>
</PropertyGroup>
Defensive patterns

Strategy: validation

Validate before calling

// Verify Roslyn can produce an interceptable location before committing to generation
var loc = semanticModel.GetInterceptableLocation(invocationSyntax, ct);
if (loc is null) { /* exclude query or raise LangVersion */ }

Try / catch

try { /* generate */ }
catch (InvalidOperationException ex) when (ex.Message.Contains("interceptable location"))
{ /* report that the query cannot be intercepted; ensure LangVersion supports interceptors */ }

Prevention

When it happens

Trigger: Generating an interceptor for a LINQ operator invocation whose source location is not interceptable per Roslyn (e.g. the call is not at a position GetInterceptableLocation can anchor to, the invocation is in generated/synthesized code, or the C# language version does not support interceptors). The null result from GetInterceptableLocation triggers the InvalidOperationException.

Common situations: Targeting a C# language version older than the one supporting interceptors (the project's LangVersion is too low). The operator call lives in source that Roslyn cannot attribute (e.g. inside another source-generated file). A query form whose terminating/intermediate operator invocation Roslyn refuses to mark as interceptable. Mismatch between the analyzer's Roslyn version and what the project compiles with.

Related errors


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