{"record":{"id":"a4ee50e8a43b5642","repo":"dotnet/efcore","slug":"the-model-must-be-finalized-and-its-runtime-depend","errorCode":null,"errorMessage":"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.","messagePattern":"The model must be finalized and its runtime dependencies must be initialized before '(.+?)' can be used\\. Ensure that either 'OnModelCreating' has completed or, if using a stand-alone 'ModelBuilder', that 'IModelRuntimeInitializer\\.Initialize\\(model\\.FinalizeModel\\(\\)\\)' was called\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Extensions/RelationalModelExtensions.cs","lineNumber":74,"sourceCode":"    /// <returns>The configuration source for the default schema.</returns>\n    public static ConfigurationSource? GetDefaultSchemaConfigurationSource(this IConventionModel model)\n        => model.FindAnnotation(RelationalAnnotationNames.DefaultSchema)?.GetConfigurationSource();\n\n    #endregion Default schema\n\n    /// <summary>\n    ///     Returns the database model.\n    /// </summary>\n    /// <param name=\"model\">The model to get the database model for.</param>\n    /// <returns>The database model.</returns>\n    public static IRelationalModel GetRelationalModel(this IModel model)\n    {\n        var relationalModel = (IRelationalModel?)model.FindRuntimeAnnotationValue(RelationalAnnotationNames.RelationalModel);\n        if (relationalModel == null)\n        {\n            var relationalModelFactory = (Func<IRelationalModel>?)model.FindRuntimeAnnotationValue(\n                    RelationalAnnotationNames.RelationalModelFactory)\n                ?? throw new InvalidOperationException(CoreStrings.ModelNotFinalized(nameof(GetRelationalModel)));\n            lock (relationalModelFactory)\n            {\n                relationalModel = model.GetOrAddRuntimeAnnotationValue(\n                    RelationalAnnotationNames.RelationalModel, f => f!(), relationalModelFactory);\n                model.RemoveRuntimeAnnotation(RelationalAnnotationNames.RelationalModelFactory);\n            }\n        }\n\n        return relationalModel;\n    }\n\n    #region Max identifier length\n\n    /// <summary>\n    ///     Returns the maximum length allowed for store identifiers.\n    /// </summary>\n    /// <param name=\"model\">The model to get the maximum identifier length for.</param>\n    /// <returns>The maximum identifier length.</returns>","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Relational/Extensions/RelationalModelExtensions.cs#L56-L92","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["If using a standalone ModelBuilder, call IModelRuntimeInitializer.Initialize(model.FinalizeModel()) before GetRelationalModel.","Let DbContext finalize the model naturally via OnModelCreating rather than querying early.","Inject IModelRuntimeInitializer and run it explicitly in test/helper code."],"exampleFix":"// before\nvar mb = new ModelBuilder();\n... configure ...\nvar rel = mb.Model.GetRelationalModel();\n// after\nvar finalized = mb.Model.FinalizeModel();\nvar initializer = ctx.GetService<IModelRuntimeInitializer>();\ninitializer.Initialize(finalized);\nvar rel = finalized.GetRelationalModel();","handlingStrategy":"validation","validationCode":"// Ensure the model is finalized and runtime-initialized before calling GetRelationalModel.\nvar finalized = modelBuilder.Model.FinalizeModel();\nctx.GetService<IModelRuntimeInitializer>().Initialize(finalized);\nvar rel = finalized.GetRelationalModel();","typeGuard":"static bool IsReady(IModel m)\n    => m.FindRuntimeAnnotationValue(RelationalAnnotationNames.RelationalModel) != null\n       || m.FindRuntimeAnnotationValue(RelationalAnnotationNames.RelationalModelFactory) != null;","tryCatchPattern":"try { return model.GetRelationalModel(); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"ModelNotFinalized\"))\n{ var f = model.FinalizeModel(); initializer.Initialize(f); return f.GetRelationalModel(); }","preventionTips":["Always run IModelRuntimeInitializer.Initialize(model.FinalizeModel()) on standalone models.","Let DbContext own finalization instead of querying relational mappings early.","Add a test that asserts GetRelationalModel works after model construction."],"tags":["model-finalization","runtime-initializer","relational-model","model-builder"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}