dotnet/efcore · error · InvalidOperationException
Trigger '{trigger}' is defined on entity type '{entityType}'
Error message
Trigger '{trigger}' is defined on entity type '{entityType}' which inherits from '{baseType}'. Triggers can only be defined on root entity types. What it means
Thrown by CosmosModelValidator.ValidateTriggerOnRootType when entityType.BaseType != null. Cosmos DB pre-triggers must be attached to the container that owns the root entity type; attaching a trigger to a derived (TPH/branch) entity type has no Cosmos-side meaning, so EF Core requires triggers only on the root of a hierarchy.
Source
Thrown at src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelValidator.cs:784
ValidateTriggerOnRootType(trigger, entityType, logger);
ValidateTriggerType(trigger, entityType, logger);
ValidateTriggerOperation(trigger, entityType, logger);
}
/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
protected virtual void ValidateTriggerOnRootType(
ITrigger trigger,
IEntityType entityType,
IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)
{
if (entityType.BaseType != null)
{
throw new InvalidOperationException(
CosmosStrings.TriggerOnDerivedType(trigger.ModelName, entityType.DisplayName(), entityType.BaseType.DisplayName()));
}
}
/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
protected virtual void ValidateTriggerType(
ITrigger trigger,
IEntityType entityType,
IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)
{
if (trigger.GetTriggerType() == null)
{
throw new InvalidOperationException(View on GitHub (pinned to dbf9771522)
Solutions
- Move the HasTrigger / Trigger configuration onto the root base entity type of the hierarchy.
- If per-derived-type behavior is needed, drive it from the trigger body using runtime type checks rather than defining separate Cosmos triggers per derived type.
Example fix
// before
modelBuilder.Entity<Manager>() // Manager : Employee
.HasTrigger("onManagerCreate");
// after
modelBuilder.Entity<Employee>() // root type
.HasTrigger("onEmployeeCreate"); Defensive patterns
Strategy: validation
Validate before calling
foreach (var et in modelBuilder.Model.GetEntityTypes())
{
foreach (var trigger in et.GetTriggers())
{
if (et.BaseType is not null)
throw new InvalidOperationException($"Trigger {trigger.ModelName} on derived type {et.DisplayName()}; move to root {et.GetRootType().DisplayName()}.");
}
} Prevention
- Define all HasTrigger configuration on root entity types only.
- In TPH hierarchies, drive per-type behavior from inside the trigger body, not from per-type trigger definitions.
When it happens
Trigger: Calling modelBuilder.Entity<DerivedType>().HasTrigger(...) or .Trigger(t => ...) where DerivedType inherits from a base entity type configured in the same model.
Common situations: Defining triggers per derived class in a TPH hierarchy expecting per-type trigger behavior. Moving trigger configuration from the base type to derived types during a refactor.
Related errors
- Trigger '{trigger}' on entity type '{entityType}' does not h
- Trigger '{trigger}' on entity type '{entityType}' does not h
- An Azure Cosmos DB container name is defined on entity type
- Cosmos automatic-indexing configuration was set on entity ty
- A partition key is defined on entity type '{entityType}', wh
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/1b11f7ba30aad902.
Report an issue: GitHub.