dotnet/efcore · error · InvalidOperationException

The model must be finalized and its runtime dependencies…

Error message

The model must be finalized and its runtime dependencies must be initialized before '{method}' can be used. Ensure that either 'OnModelCreating' has completed or, if using a stand-alone 'ModelBuilder', that 'IModelRuntimeInitializer.Initialize(model.FinalizeModel())' was called.

What it means

GetRelationalDependencies throws ModelNotFinalized when the model lacks the ModelDependencies runtime annotation, meaning it was never run through IModelRuntimeInitializer.Initialize(model.FinalizeModel()). Relational dependencies are attached only at runtime-model finalization; calling relational runtime APIs on a partially built IModel is a programming error.

Solutions

  1. Run IModelRuntimeInitializer.Initialize(model.FinalizeModel()) before calling the method named in the error.
  2. Inside a DbContext, ensure OnModelCreating returns without exception; the runtime initializer runs after OnModelCreating.
  3. In tests, obtain the finalized model via the DbContext (DbContext.Model) rather than a raw ModelBuilder product.

Example fix

// before
var mb = new ModelBuilder(new ConventionSet());
mb.Entity<Blog>();
var deps = mb.Model.GetRelationalDependencies(); // throws

// after
var finalized = mb.FinalizeModel();
var initializer = new RuntimeModelInitializer(/* services */);
initializer.Initialize(finalized);
var deps = finalized.GetRelationalDependencies();
Defensive patterns

Strategy: validation

Validate before calling

var initialized = runtimeInitializer.Initialize(model.FinalizeModel());
var deps = initialized.GetRelationalDependencies();

Type guard

static bool IsFinalized(IModel m)
    => m.FindRuntimeAnnotation(RelationalAnnotationNames.ModelDependencies) is not null;

Prevention

When it happens

Trigger: Constructing a ModelBuilder standalone (not via DbContext.OnModelCreating) and immediately calling a relational extension that needs RelationalModelDependencies — e.g. GetRelationalDependencies, runtime annotation accessors that depend on it. The [CallerMemberName] is injected into the message so the offending method is named.

Common situations: Provider authors writing tests against an unfinalized convention model; tooling that reads the model before it is published; calling relational APIs on model.GetModel() from a convention without running finalization; OnModelCreating throwing before completion leaving a half-built model.

Related errors


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

Appendix: source

Thrown at src/EFCore.Relational/Infrastructure/RelationalModelExtensions.cs:28

/// </summary>
public static class RelationalModelExtensions
{
    /// <summary>
    ///     Returns the relational service dependencies.
    /// </summary>
    /// <remarks>
    ///     See <see href="https://aka.ms/efcore-docs-providers">Implementation of database providers and extensions</see>
    ///     for more information and examples.
    /// </remarks>
    /// <param name="model">The model.</param>
    /// <param name="methodName">The name of the calling method.</param>
    /// <returns>The relational service dependencies.</returns>
    public static RelationalModelDependencies GetRelationalDependencies(
        this IModel model,
        [CallerMemberName] string methodName = "")
        => (RelationalModelDependencies?)model
                .FindRuntimeAnnotation(RelationalAnnotationNames.ModelDependencies)?.Value
            ?? throw new InvalidOperationException(CoreStrings.ModelNotFinalized(methodName));
}

View on GitHub (pinned to 3a2006ef56)