dotnet/efcore · error · OperationException

The migration name ' ' is not valid. Migration names cannot…

Error message

The migration name '{name}' is not valid. Migration names cannot contain any of the following characters: '{characters}'.

What it means

PrepareForMigration checks the migration name against Path.GetInvalidFileNameChars() because the name is used as a file name (the migration id is '<Name>_<Timestamp>'). Any invalid character (e.g. ':', '\\', '/', '*', '?', '"', '<', '>', '|') is rejected and listed in the message so the user knows exactly which characters to remove.

Solutions

  1. Use an alphanumeric, PascalCase name with no path separators or reserved punctuation (e.g. 'AddOrderTable').
  2. Strip any of: <>:"/\\|?* and control characters from the proposed name before running the command.
  3. If you wanted namespacing, use the --namespace flag instead of embedding separators in the name.

Example fix

# before
dotnet ef migrations add Add:Order
# after
dotnet ef migrations add AddOrder
Defensive patterns

Strategy: validation

Validate before calling

var invalid = Path.GetInvalidFileNameChars();
if (name.Any(c => invalid.Contains(c)))
{
    throw new ArgumentException($"Migration name contains invalid characters: {string.Join(", ", name.Where(c => invalid.Contains(c)))}");
}

Try / catch

try { operations.AddMigration(name, ...); }
catch (OperationException ex) when (ex.Message.Contains("is not valid. Migration names cannot contain"))
{ /* sanitize the name and retry */ }

Prevention

When it happens

Trigger: Calling PrepareForMigration with a name containing any OS-invalid filename character. Cross-platform tooling uses the union of invalid chars; on Windows this includes the classic reserved set.

Common situations: Naming a migration with a date containing slashes ('2024/01/Init'), with a namespace dot-path style that includes '\\', or with punctuation like 'Add:Orders'; copy-pasting a name with trailing/leading spaces or quotes.

Related errors


AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11). Data as JSON: /api/errors/1c6b059e38b2d9e9. Report an issue: GitHub.

Appendix: source

Thrown at src/EFCore.Design/Design/Internal/MigrationsOperations.cs:448

        return files;
    }

    /// <summary>
    ///     Prepares common resources for migration operations.
    /// </summary>
    public virtual IServiceProvider PrepareForMigration(string name, DbContext context)
    {
        if (string.IsNullOrWhiteSpace(name))
        {
            throw new OperationException(DesignStrings.MigrationNameRequired);
        }

        var invalidPathChars = Path.GetInvalidFileNameChars();
        if (name.Any(c => invalidPathChars.Contains(c)))
        {
            throw new OperationException(
                DesignStrings.BadMigrationName(name, string.Join("','", invalidPathChars)));
        }

        var contextClassName = context.GetType().Name;
        if (string.Equals(name, contextClassName, StringComparison.Ordinal))
        {
            throw new OperationException(
                DesignStrings.ConflictingContextAndMigrationName(name));
        }

        var services = _servicesBuilder.Build(context);
        EnsureServices(services);

        return services;
    }

    private static void EnsureServices(IServiceProvider services)
    {
        var migrator = services.GetService<IMigrator>();
        if (migrator == null)

View on GitHub (pinned to 3a2006ef56)