dotnet/efcore · error · InvalidOperationException

The model must be finalized and its runtime dependencies mus

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

IModel.GetRelationalModel() builds the relational mapping only after the model is finalized and its runtime initializer has attached the RelationalModelFactory runtime annotation (RelationalModelExtensions.cs:74, CoreStrings.ModelNotFinalized). On a raw, unfinalized IModel the factory annotation is absent, so the call cannot proceed.

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

Solutions

  1. Finalize + initialize: var finalized = modelBuilder.FinalizeModel(); var runtime = serviceProvider.GetService<IModelRuntimeInitializer>()!.Initialize(finalized); then call GetRelationalModel() on the runtime model.
  2. In app code, get the model from a constructed DbContext (dbContext.Model) — it is already runtime-initialized.
  3. If using a design-time context, ensure its OnModelCreating has run before accessing GetRelationalModel().

Example fix

// before
var mb = new ModelBuilder();
mb.Entity<Order>();
var rel = mb.Model.GetRelationalModel();   // throws: not finalized

// after
var finalized = mb.FinalizeModel();
var initializer = ctx.GetService<IModelRuntimeInitializer>();
var runtime = initializer.Initialize(finalized);
var rel = runtime.GetRelationalModel();
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the model is finalized + runtime-initialized before GetRelationalModel.
var finalized = modelBuilder.FinalizeModel();
var initializer = scope.ServiceProvider.GetRequiredService<IModelRuntimeInitializer>();
var runtime = initializer.Initialize(finalized);
var rel = runtime.GetRelationalModel();

Prevention

When it happens

Trigger: Calling model.GetRelationalModel() on an IModel from an un-finalized standalone ModelBuilder, or before DbContext.OnModelCreating completes; using a cached/partially-built model in a provider that expects the runtime model.

Common situations: Unit tests that build a ModelBuilder, configure entities, then immediately call GetRelationalModel() without finalizing; tooling that reads the relational model from a ModelBuilder.Model snapshot before FinalizeModel().

Related errors


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