dotnet/efcore · error · InvalidOperationException

A compilation must be loaded.

Error message

A compilation must be loaded.

What it means

`Translate` guards on `_compilation is null` and throws `InvalidOperationException(CompilationMustBeLoaded)` if the translator was never initialized. `Load(compilation, userDbContext, additionalAssembly)` is the only thing that sets `_compilation`, so calling `Translate` first is an ordering bug.

Source

Thrown at src/EFCore.Design/Query/Internal/CSharpToLinqTranslator.cs:94

    /// <summary>
    ///     Translates a Roslyn syntax tree into a LINQ expression tree.
    /// </summary>
    /// <param name="node">The Roslyn syntax node to be translated.</param>
    /// <param name="semanticModel">
    ///     The <see cref="SemanticModel" /> for the Roslyn <see cref="SyntaxTree" /> of which <paramref name="node" /> is a part.
    /// </param>
    /// <returns>A LINQ expression tree translated from the provided <paramref name="node" />.</returns>
    /// <remarks>
    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
    ///     any release. You should only use it directly in your code with extreme caution and knowing that
    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
    /// </remarks>
    public virtual Expression Translate(SyntaxNode node, SemanticModel semanticModel)
    {
        if (_compilation is null)
        {
            throw new InvalidOperationException(DesignStrings.CompilationMustBeLoaded);
        }

        Check.DebugAssert(
            ReferenceEquals(semanticModel.SyntaxTree, node.SyntaxTree),
            "Provided semantic model doesn't match the provided syntax node");

        _semanticModel = semanticModel;

        // Perform data flow analysis to detect all variables flowing into the query (e.g. captured variables)
        _dataFlowsIn.Clear();
        foreach (var flowsIn in _semanticModel.AnalyzeDataFlow(node).DataFlowsIn)
        {
            _dataFlowsIn[flowsIn] = null;
        }

        var result = Visit(node);

        Debug.Assert(_parameterStack.Count == 1);

View on GitHub (pinned to dbf9771522)

Solutions

  1. Call `translator.Load(compilation, dbContext, additionalAssembly)` exactly once before any `Translate` call.
  2. Guard the entry point so `Translate` is never reached on an uninitialized instance.

Example fix

// before
var expr = translator.Translate(node, semanticModel);
// after
translator.Load(compilation, dbContext);
var expr = translator.Translate(node, semanticModel);
Defensive patterns

Strategy: validation

Validate before calling

// Guard Translate on the uninitialized state.
if (translatorIsLoaded) // track whether Load was called
    translator.Translate(node, semanticModel);
else
    throw new InvalidOperationException("Call CSharpToLinqTranslator.Load(...) before Translate.");

Try / catch

try { translator.Translate(node, semanticModel); }
catch (InvalidOperationException ex) when (ex.Message == "A compilation must be loaded.")
{ /* call translator.Load(...) then retry */ }

Prevention

When it happens

Trigger: Instantiating `CSharpToLinqTranslator` and calling `Translate(node, semanticModel)` before invoking `Load(...)`. The field is declared `Compilation? _compilation` precisely to support this check.

Common situations: A custom host/wrapper that wires up the translator out of order, or a refactor that moved the `Load` call behind a condition that evaluated false.

Related errors


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