{"record":{"id":"3cf3fbdc270d08be","repo":"dotnet/efcore","slug":"trigger-trigger-on-entity-type-entitytype","errorCode":null,"errorMessage":"Trigger '{trigger}' on entity type '{entityType}' does not have a trigger type configured. Use 'HasTriggerType()' to configure the trigger type.","messagePattern":"Trigger '(.+?)' on entity type '(.+?)' does not have a trigger type configured\\. Use 'HasTriggerType\\(\\)' to configure the trigger type\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelValidator.cs","lineNumber":802,"sourceCode":"            throw new InvalidOperationException(\n                CosmosStrings.TriggerOnDerivedType(trigger.ModelName, entityType.DisplayName(), entityType.BaseType.DisplayName()));\n        }\n    }\n\n    /// <summary>\n    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to\n    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in\n    ///     any release. You should only use it directly in your code with extreme caution and knowing that\n    ///     doing so can result in application failures when updating to a new Entity Framework Core release.\n    /// </summary>\n    protected virtual void ValidateTriggerType(\n        ITrigger trigger,\n        IEntityType entityType,\n        IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)\n    {\n        if (trigger.GetTriggerType() == null)\n        {\n            throw new InvalidOperationException(\n                CosmosStrings.TriggerMissingType(trigger.ModelName, entityType.DisplayName()));\n        }\n    }\n\n    /// <summary>\n    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to\n    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in\n    ///     any release. You should only use it directly in your code with extreme caution and knowing that\n    ///     doing so can result in application failures when updating to a new Entity Framework Core release.\n    /// </summary>\n    protected virtual void ValidateTriggerOperation(\n        ITrigger trigger,\n        IEntityType entityType,\n        IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)\n    {\n        if (trigger.GetTriggerOperation() == null)\n        {\n            throw new InvalidOperationException(","sourceCodeStart":784,"sourceCodeEnd":820,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelValidator.cs#L784-L820","documentation":"Thrown by CosmosModelValidator.ValidateTriggerType when trigger.GetTriggerType() returns null. Cosmos requires every trigger to declare a TriggerType (Pre/Post) via CosmosTriggerBuilderExtensions.HasTriggerType; without it the provider cannot register the trigger in the container.","triggerScenarios":"Calling HasTrigger(\"name\") on an entity but never chaining .HasTriggerType(TriggerType.Pre/Post) on the returned builder.","commonSituations":"Defining a trigger by name only and forgetting the Cosmos-specific type; refactoring trigger setup and dropping the type line; converting triggers from data annotations that do not carry the Cosmos type.","solutions":["Chain .HasTriggerType(TriggerType.Pre) or .HasTriggerType(TriggerType.Post) onto the trigger builder returned by HasTrigger(...).","Confirm the trigger builder is not null (HasTrigger may return null if conflicting configuration exists).","Re-run model validation to ensure the type annotation is now set."],"exampleFix":"// before\nmodelBuilder.Entity<Doc>().HasTrigger(\"ValidateDoc\");\n\n// after\nmodelBuilder.Entity<Doc>()\n    .HasTrigger(\"ValidateDoc\")!\n    .HasTriggerType(TriggerType.Pre);","handlingStrategy":"validation","validationCode":"// Ensure every trigger has a type.\nforeach (var et in modelBuilder.Model.GetEntityTypes())\nforeach (var t in et.GetTriggers())\n    if (t.GetTriggerType() is null)\n        throw new InvalidOperationException($\"Trigger {t.ModelName} on {et.DisplayName()} needs HasTriggerType().\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always chain .HasTriggerType(...) after HasTrigger(...).","Wrap trigger setup in a helper that asserts both type and operation are set.","Add a model-validation unit test covering trigger configuration."],"tags":["cosmos","triggers","model-validation","configuration"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}