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

GetRelationalModel() builds and caches the relational database model from a runtime annotation holding a factory (RelationalModelFactory). If that factory annotation is absent, the model was never finalized and its runtime dependencies were never initialized, so EF Core throws directing you to call FinalizeModel / IModelRuntimeInitializer.Initialize first.

Solutions

  1. If using a standalone ModelBuilder, call IModelRuntimeInitializer.Initialize(model.FinalizeModel()) before GetRelationalModel.
  2. Let DbContext finalize the model naturally via OnModelCreating rather than querying early.
  3. Inject IModelRuntimeInitializer and run it explicitly in test/helper code.

Example fix

// before
var mb = new ModelBuilder();
... configure ...
var rel = mb.Model.GetRelationalModel();
// after
var finalized = mb.Model.FinalizeModel();
var initializer = ctx.GetService<IModelRuntimeInitializer>();
initializer.Initialize(finalized);
var rel = finalized.GetRelationalModel();
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the model is finalized and runtime-initialized before calling GetRelationalModel.
var finalized = modelBuilder.Model.FinalizeModel();
ctx.GetService<IModelRuntimeInitializer>().Initialize(finalized);
var rel = finalized.GetRelationalModel();

Type guard

static bool IsReady(IModel m)
    => m.FindRuntimeAnnotationValue(RelationalAnnotationNames.RelationalModel) != null
       || m.FindRuntimeAnnotationValue(RelationalAnnotationNames.RelationalModelFactory) != null;

Try / catch

try { return model.GetRelationalModel(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("ModelNotFinalized"))
{ var f = model.FinalizeModel(); initializer.Initialize(f); return f.GetRelationalModel(); }

Prevention

When it happens

Trigger: Calling model.GetRelationalModel() on a model that has not been finalized — e.g. a standalone ModelBuilder's model that was never passed through IModelRuntimeInitializer.Initialize(model.FinalizeModel()), or an OnModelCreating that has not completed.

Common situations: Test code building a model with new ModelBuilder() and querying relational mappings directly; calling GetRelationalModel before the context has finished initializing; custom model construction pipelines skipping the runtime initializer.

Related errors


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

Appendix: source

Thrown at src/EFCore.Relational/Extensions/RelationalModelExtensions.cs:74

    /// <returns>The configuration source for the default schema.</returns>
    public static ConfigurationSource? GetDefaultSchemaConfigurationSource(this IConventionModel model)
        => model.FindAnnotation(RelationalAnnotationNames.DefaultSchema)?.GetConfigurationSource();

    #endregion Default schema

    /// <summary>
    ///     Returns the database model.
    /// </summary>
    /// <param name="model">The model to get the database model for.</param>
    /// <returns>The database model.</returns>
    public static IRelationalModel GetRelationalModel(this IModel model)
    {
        var relationalModel = (IRelationalModel?)model.FindRuntimeAnnotationValue(RelationalAnnotationNames.RelationalModel);
        if (relationalModel == null)
        {
            var relationalModelFactory = (Func<IRelationalModel>?)model.FindRuntimeAnnotationValue(
                    RelationalAnnotationNames.RelationalModelFactory)
                ?? throw new InvalidOperationException(CoreStrings.ModelNotFinalized(nameof(GetRelationalModel)));
            lock (relationalModelFactory)
            {
                relationalModel = model.GetOrAddRuntimeAnnotationValue(
                    RelationalAnnotationNames.RelationalModel, f => f!(), relationalModelFactory);
                model.RemoveRuntimeAnnotation(RelationalAnnotationNames.RelationalModelFactory);
            }
        }

        return relationalModel;
    }

    #region Max identifier length

    /// <summary>
    ///     Returns the maximum length allowed for store identifiers.
    /// </summary>
    /// <param name="model">The model to get the maximum identifier length for.</param>
    /// <returns>The maximum identifier length.</returns>

View on GitHub (pinned to 3a2006ef56)