dotnet/efcore · error · InvalidOperationException
The number of column types ({typesCount}) doesn't match the
Error message
The number of column types ({typesCount}) doesn't match the number of columns ({columnsCount}) for the data insertion operation on '{table}'. Provide the same number of column types and columns. What it means
Thrown inside GenerateModificationCommands(InsertDataOperation, ...) in src/EFCore.Relational/Migrations/MigrationsSqlGenerator.cs:884 (message key InsertDataOperationTypesCountMismatch). It throws InvalidOperationException when operation.ColumnTypes is non-null but its length differs from operation.Columns.Length. ColumnTypes is an optional explicit type override array; if you supply it, it must line up element-for-element with Columns.
Source
Thrown at src/EFCore.Relational/Migrations/MigrationsSqlGenerator.cs:884
/// <param name="operation">The data operation to generate commands for.</param>
/// <param name="model">The model.</param>
/// <returns>The commands that correspond to the given operation.</returns>
protected virtual IEnumerable<IReadOnlyModificationCommand> GenerateModificationCommands(
InsertDataOperation operation,
IModel? model)
{
if (operation.Columns.Length != operation.Values.GetLength(1))
{
throw new InvalidOperationException(
RelationalStrings.InsertDataOperationValuesCountMismatch(
operation.Values.GetLength(1), operation.Columns.Length,
FormatTable(operation.Table, operation.Schema ?? model?.GetDefaultSchema())));
}
if (operation.ColumnTypes != null
&& operation.Columns.Length != operation.ColumnTypes.Length)
{
throw new InvalidOperationException(
RelationalStrings.InsertDataOperationTypesCountMismatch(
operation.ColumnTypes.Length, operation.Columns.Length,
FormatTable(operation.Table, operation.Schema ?? model?.GetDefaultSchema())));
}
if (operation.ColumnTypes == null
&& model == null)
{
throw new InvalidOperationException(
RelationalStrings.InsertDataOperationNoModel(
FormatTable(operation.Table, operation.Schema ?? model?.GetDefaultSchema())));
}
var propertyMappings = operation.ColumnTypes == null
? GetPropertyMappings(operation.Columns, operation.Table, operation.Schema, model)
: null;
for (var i = 0; i < operation.Values.GetLength(0); i++)View on GitHub (pinned to dbf9771522)
Solutions
- Make operation.ColumnTypes either null (so types are resolved from the model) or an array with exactly operation.Columns.Length elements.
- Re-scaffold the migration to regenerate consistent columnTypes arrays.
- Add the entity to the model (modelBuilder.Entity<T>()) and use HasData so column types are inferred and columnTypes can be omitted.
- Audit the migration so that for every i, Columns[i] pairs with ColumnTypes[i].
Example fix
// before (2 columns but 1 column type):
migrationBuilder.InsertData(
table: "Users",
columns: new[] { "Id", "Name" },
columnTypes: new[] { "int" },
values: new object[,] { { 1, "Alice" } });
// after (aligned):
migrationBuilder.InsertData(
table: "Users",
columns: new[] { "Id", "Name" },
columnTypes: new[] { "int", "nvarchar(100)" },
values: new object[,] { { 1, "Alice" } }); Defensive patterns
Strategy: validation
Validate before calling
static bool InsertTypesAreValid(string[] columns, string[]? columnTypes)
{
return columnTypes == null || columnTypes.Length == columns.Length;
}
// usage
if (!InsertTypesAreValid(columns, columnTypes))
throw new InvalidOperationException("columnTypes.Length must equal columns.Length (or be null)"); Try / catch
try
{
await dbContext.Database.MigrateAsync();
}
catch (InvalidOperationException ex) when (ex.Message.Contains("number of column types") && ex.Message.Contains("data insertion"))
{
logger.LogError(ex, "An InsertDataOperation has a columnTypes/columns length mismatch; fix the migration.");
throw;
} Prevention
- Omit columnTypes entirely when an entity maps the table (types come from the model).
- When supplying columnTypes, keep them in the same order and count as columns.
- Re-scaffold migrations after column changes rather than hand-editing type arrays.
- Add a test asserting columnTypes == null || columnTypes.Length == columns.Length.
When it happens
Trigger: A migration calls migrationBuilder.InsertData with the columnTypes: parameter set to an array whose length differs from columns:. For example columns: new[] { "A", "B" } with columnTypes: new[] { "int" }. Common after editing an auto-generated migration and removing a column type without removing the column.
Common situations: Manually adding columnTypes to an InsertData and miscounting. Editing a migration to remove a column but forgetting to remove the corresponding columnType entry. Using model-less migrations where types must be specified by hand.
Related errors
- The number of values ({valuesCount}) doesn't match the numbe
- The data insertion operation on '{table}' is not associated
- The number of key values ({valuesCount}) doesn't match the n
- The number of key column types ({typesCount}) doesn't match
- The number of key values ({valuesCount}) doesn't match the n
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/193f9645298e6829.
Report an issue: GitHub.