dotnet/efcore · error · InvalidOperationException
Trigger ' ' is defined on entity type ' ' which inherits…
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 a trigger is defined on an entity type whose BaseType is not null. Cosmos DB stored-procedure triggers are scoped to containers (root entity types); defining them on a derived entity in a TPH hierarchy is not meaningful, so the validator rejects it.
Solutions
- Move the HasTrigger(...) call from the derived entity to the root entity type of the hierarchy.
- If the trigger really must fire only for a specific discriminator, register it on the root and filter inside the trigger body using the discriminator value.
- Remove the trigger if it is not required for the Cosmos provider.
Example fix
// before
modelBuilder.Entity<Derived>().HasTrigger("OnDerivedInsert"); // Derived : Base
// after
modelBuilder.Entity<Base>().HasTrigger("OnInsert"); // triggers live on the root Defensive patterns
Strategy: validation
Validate before calling
// Reject triggers on derived types before the runtime does.
foreach (var et in modelBuilder.Model.GetEntityTypes())
foreach (var t in et.GetTriggers())
if (et.BaseType is not null)
throw new InvalidOperationException($"Trigger {t.ModelName} must be defined on root type {et.GetRootType().DisplayName()}."); Prevention
- Define Cosmos triggers only on root entity types.
- When sharing a base entity across providers, isolate trigger config in provider-specific IEntityTypeConfiguration classes.
- Run a startup scan of GetTriggers() vs BaseType.
When it happens
Trigger: Calling HasTrigger(...) on an entity that derives from another entity (entityType.BaseType != null) in a Cosmos model.
Common situations: Sharing a base entity across providers and defining triggers on derived types; copying trigger configuration from a relational TPC/TPT model into Cosmos.
Related errors
- Trigger ' ' on entity type ' ' does not have a trigger type…
- Trigger ' ' on entity type ' ' does not have a trigger…
- A full-text index is defined for
- A full-text index on
- A partition key is defined on entity type
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/1b11f7ba30aad902.
Report an issue: GitHub.
Appendix: 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 3a2006ef56)