dotnet/efcore · error · InvalidOperationException

Trigger '{trigger}' on entity type '{entityType}' does not h

Error message

Trigger '{trigger}' on entity type '{entityType}' does not have a trigger operation configured. Use 'HasTriggerOperation()' to configure the trigger operation.

What it means

Thrown by CosmosModelValidator.ValidateTriggerOperation when trigger.GetTriggerOperation() returns null. Cosmos triggers must declare the operation they fire on (Create/Replace/Delete/All); without it the trigger definition is incomplete and EF Core rejects it before sending it to the container.

Source

Thrown at src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelValidator.cs:820

            throw new InvalidOperationException(
                CosmosStrings.TriggerMissingType(trigger.ModelName, entityType.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 ValidateTriggerOperation(
        ITrigger trigger,
        IEntityType entityType,
        IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)
    {
        if (trigger.GetTriggerOperation() == null)
        {
            throw new InvalidOperationException(
                CosmosStrings.TriggerMissingOperation(trigger.ModelName, entityType.DisplayName()));
        }
    }
}

View on GitHub (pinned to dbf9771522)

Solutions

  1. Provide the operation via HasTriggerOperation(CosmosTriggerOperation.Create) (or Replace/Delete/All).
  2. Prefer the HasTrigger(name, type, operation) overload that takes all three at once to avoid leaving facets unset.

Example fix

// before
modelBuilder.Entity<Order>()
    .HasTrigger("validateOrder", CosmosTriggerType.Pre);

// after
modelBuilder.Entity<Order>()
    .HasTrigger("validateOrder", CosmosTriggerType.Pre, CosmosTriggerOperation.Create);
Defensive patterns

Strategy: validation

Validate before calling

foreach (var et in modelBuilder.Model.GetEntityTypes())
{
    foreach (var trigger in et.GetTriggers())
    {
        if (trigger.GetTriggerOperation() is null)
            throw new InvalidOperationException($"Trigger {trigger.ModelName} on {et.DisplayName()} has no trigger operation.");
    }
}

Prevention

When it happens

Trigger: Calling HasTrigger with a type but no operation, e.g. HasTrigger("t", CosmosTriggerType.Pre) without specifying the operation, or any path that sets the trigger type facet but not the operation facet.

Common situations: Setting HasTriggerType but forgetting the matching HasTriggerOperation. Using an older API overload that did not require the operation.

Related errors


AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06). Data as JSON: /api/errors/26ee8a2590bd1f6d. Report an issue: GitHub.