{"record":{"id":"0cc1dba5d1b3a284","repo":"dotnet/efcore","slug":"a-synchronous-store-management-operation-was-perfo-0cc1db","errorCode":null,"errorMessage":"A synchronous store management operation was performed and no synchronous seed delegate has been provided, however an asynchronous seed delegate was. Set 'UseSeeding' option with a delegate equivalent to the one supplied in 'UseAsyncSeeding'.","messagePattern":"A synchronous store management operation was performed and no synchronous seed delegate has been provided, however an asynchronous seed delegate was\\. Set 'UseSeeding' option with a delegate equivalent to the one supplied in 'UseAsyncSeeding'\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Migrations/Internal/Migrator.cs","lineNumber":203,"sourceCode":"                    getCommands(), _connection, state, commitTransaction: useTransaction, MigrationTransactionIsolationLevel);\n            }\n\n            var coreOptionsExtension =\n                _contextOptions.FindExtension<CoreOptionsExtension>()\n                ?? new CoreOptionsExtension();\n\n            var seed = coreOptionsExtension.Seeder;\n            if (seed != null)\n            {\n                if (!state.SeedingCompleted)\n                {\n                    seed(context, state.AnyOperationPerformed);\n                    state.SeedingCompleted = true;\n                }\n            }\n            else if (coreOptionsExtension.AsyncSeeder != null)\n            {\n                throw new InvalidOperationException(CoreStrings.MissingSeeder);\n            }\n\n            state.Transaction?.Commit();\n            return state.AnyOperationPerformed;\n        }\n        finally\n        {\n            state.DatabaseLock?.Dispose();\n            state.DatabaseLock = null;\n            state.Transaction?.Dispose();\n            state.Transaction = null;\n            _connection.Close();\n        }\n    }\n\n    /// <summary>\n    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to\n    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Relational/Migrations/Internal/Migrator.cs#L185-L221","documentation":"The synchronous Migrator path ran a store-management/migration operation. The configured DbContextOptions has an async seeder (UseAsyncSeeding) but no synchronous seeder (UseSeeding), so the sync path has nothing to call. EF requires the two delegates to be supplied as a matching pair so sync and async execution are both covered.","triggerScenarios":"optionsBuilder.UseAsyncSeeding(...) was called without a matching UseSeeding(...), and a synchronous migration API is invoked (e.g. context.Database.Migrate(), Database.EnsureCreated(), or Migrator.Migrate on a sync code path).","commonSituations":"App configured only async seeding because the rest of the app is async, but a sync startup or test harness calls EnsureCreated/Migrate; upgrading from an older EF version that had a single seeding hook; copy-paste that lost the UseSeeding call.","solutions":["Add optionsBuilder.UseSeeding((ctx, anyOp) => { ... }) with a sync equivalent of your async seeder.","Keep UseSeeding and UseAsyncSeeding logic in sync (call the same helper from both).","If the operation must be async-only, switch the caller to the async API (MigrateAsync) so the sync path is never reached."],"exampleFix":"// before\noptions.UseSqlServer(conn)\n       .UseAsyncSeeding(async (ctx, anyOp, ct) =>\n       {\n           await ctx.Products.AddAsync(new Product { Id = 1 }, ct);\n           await ctx.SaveChangesAsync(ct);\n       });\n\n// after\noptions.UseSqlServer(conn)\n       .UseSeeding((ctx, anyOp) =>\n       {\n           ctx.Products.Add(new Product { Id = 1 });\n           ctx.SaveChanges();\n       })\n       .UseAsyncSeeding(async (ctx, anyOp, ct) =>\n       {\n           await ctx.Products.AddAsync(new Product { Id = 1 }, ct);\n           await ctx.SaveChangesAsync(ct);\n       });","handlingStrategy":"validation","validationCode":"// At startup, assert the seeder pair is configured together\nstatic void EnsureSeederPair(DbContextOptions opts)\n{\n    var ext = opts.FindExtension<CoreOptionsExtension>();\n    if ((ext?.Seeder == null) ^ (ext?.AsyncSeeder == null))\n        throw new InvalidOperationException(\n            \"Configure both UseSeeding and UseAsyncSeeding together.\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always configure UseSeeding and UseAsyncSeeding as a matched pair.","Add a startup check that verifies both delegates are non-null.","Prefer the async API (MigrateAsync) in async hosts to avoid the sync path entirely."],"tags":["migrations","seeding","configuration","sync-async"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}