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

  1. Move the HasTrigger(...) call from the derived entity to the root entity type of the hierarchy.
  2. 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.
  3. 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

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


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)