dotnet/efcore · error · InvalidOperationException
The current CSharpMigrationOperationGenerator cannot scaffol
Error message
The current CSharpMigrationOperationGenerator cannot scaffold operations of type '{operationType}'. Configure your design-time services to use one that can. What it means
CSharpMigrationOperationGenerator.Generate dispatches each MigrationOperation via a dynamic overload (line 58). If no specific Generate(TOperation) overload matches the runtime type, the call resolves to the base Generate(MigrationOperation, builder) which throws this InvalidOperationException. The fix is always to add a generator that knows your custom operation type.
Source
Thrown at src/EFCore.Design/Migrations/Design/CSharpMigrationOperationGenerator.cs:69
{
builder
.AppendLine()
.AppendLine();
}
builder.Append(builderName);
Generate((dynamic)operation, builder);
builder.Append(";");
}
}
/// <summary>
/// Generates code for an unknown <see cref="MigrationOperation" />.
/// </summary>
/// <param name="operation">The operation.</param>
/// <param name="builder">The builder code is added to.</param>
protected virtual void Generate(MigrationOperation operation, IndentedStringBuilder builder)
=> throw new InvalidOperationException(DesignStrings.UnknownOperation(operation.GetType()));
/// <summary>
/// Generates code for an <see cref="AddColumnOperation" />.
/// </summary>
/// <param name="operation">The operation.</param>
/// <param name="builder">The builder code is added to.</param>
protected virtual void Generate(AddColumnOperation operation, IndentedStringBuilder builder)
{
builder
.Append(".AddColumn<")
.Append(Code.Reference(operation.ClrType))
.AppendLine(">(");
using (builder.Indent())
{
builder
.Append("name: ")
.Append(Code.Literal(operation.Name));View on GitHub (pinned to dbf9771522)
Solutions
- Subclass CSharpMigrationOperationGenerator and add 'protected virtual void Generate(MyOperation op, IndentedStringBuilder b)'.
- Register your generator in design-time services via IDesignTimeServices.ConfigureDesignTimeServices replacing ICSharpMigrationOperationGenerator.
- If the operation is only SQL-relevant, also implement the corresponding SQL generator so the operation executes.
- Re-add the migration after registering the generator so it re-scaffolds using the new overload.
Example fix
// before: MyCreateTriggerOperation has no generator overload
public class MyCSharpMigrationOperationGenerator : CSharpMigrationOperationGenerator
{
public MyCSharpMigrationOperationGenerator(CSharpMigrationOperationGeneratorDependencies d) : base(d) { }
protected virtual void Generate(MyCreateTriggerOperation op, IndentedStringBuilder b)
=> b.AppendLine($".CreateTrigger(name: {Code.Literal(op.Name)})");
}
// register:
services.AddSingleton<ICSharpMigrationOperationGenerator, MyCSharpMigrationOperationGenerator>(); Defensive patterns
Strategy: validation
Validate before calling
var known = new HashSet<Type>(supportedOperationTypes);
foreach (var op in migration.Operations)
if (!known.Contains(op.GetType())) throw new InvalidOperationException($"No generator for operation type {op.GetType()}."); Type guard
static bool CanGenerate(CSharpMigrationOperationGenerator g, MigrationOperation op)
{ try { g.GetType().GetMethod("Generate", new[] { op.GetType(), typeof(IndentedStringBuilder) }); return true; } catch { return false; } } Prevention
- Always pair a custom MigrationOperation with a generator overload.
- Register the generator via IDesignTimeServices so it is picked up at scaffold time.
- Add a unit test that scaffolds a migration containing each custom operation type.
When it happens
Trigger: A custom MigrationOperation subclass (e.g. MyCreateTriggerOperation) is present in a migration's Up/Down list, but the registered CSharpMigrationOperationGenerator has no overload for it. The dynamic dispatch falls through to the fallback at line 68-69.
Common situations: Building a custom provider/extension that introduces a new MigrationOperation type but forgot to register a matching ICSharpMigrationOperationGenerator (or a derived CSharpMigrationOperationGenerator with the overload); upgrading EF Core removed an overload your provider relied on.
Related errors
- No DbContext named '{name}' was found.
- The wildcard '*' can only be used with commands that run for
- No DbContext was found in assembly '{assembly}'. Ensure that
- Changes have been made to the model since the last migration
- A migration name must be specified.
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/eb576e7e163b38db.
Report an issue: GitHub.