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

  1. Subclass CSharpMigrationOperationGenerator and add 'protected virtual void Generate(MyOperation op, IndentedStringBuilder b)'.
  2. Register your generator in design-time services via IDesignTimeServices.ConfigureDesignTimeServices replacing ICSharpMigrationOperationGenerator.
  3. If the operation is only SQL-relevant, also implement the corresponding SQL generator so the operation executes.
  4. 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

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


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