{"record":{"id":"1b11f7ba30aad902","repo":"dotnet/efcore","slug":"trigger-trigger-is-defined-on-entity-type-en","errorCode":null,"errorMessage":"Trigger '{trigger}' is defined on entity type '{entityType}' which inherits from '{baseType}'. Triggers can only be defined on root entity types.","messagePattern":"Trigger '(.+?)' is defined on entity type '(.+?)' which inherits from '(.+?)'\\. Triggers can only be defined on root entity types\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelValidator.cs","lineNumber":784,"sourceCode":"        ValidateTriggerOnRootType(trigger, entityType, logger);\n        ValidateTriggerType(trigger, entityType, logger);\n        ValidateTriggerOperation(trigger, entityType, logger);\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 ValidateTriggerOnRootType(\n        ITrigger trigger,\n        IEntityType entityType,\n        IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)\n    {\n        if (entityType.BaseType != null)\n        {\n            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(","sourceCodeStart":766,"sourceCodeEnd":802,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelValidator.cs#L766-L802","documentation":"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.","triggerScenarios":"Calling HasTrigger(...) on an entity that derives from another entity (entityType.BaseType != null) in a Cosmos model.","commonSituations":"Sharing a base entity across providers and defining triggers on derived types; copying trigger configuration from a relational TPC/TPT model into Cosmos.","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."],"exampleFix":"// before\nmodelBuilder.Entity<Derived>().HasTrigger(\"OnDerivedInsert\");  // Derived : Base\n\n// after\nmodelBuilder.Entity<Base>().HasTrigger(\"OnInsert\");          // triggers live on the root","handlingStrategy":"validation","validationCode":"// Reject triggers on derived types before the runtime does.\nforeach (var et in modelBuilder.Model.GetEntityTypes())\nforeach (var t in et.GetTriggers())\n    if (et.BaseType is not null)\n        throw new InvalidOperationException($\"Trigger {t.ModelName} must be defined on root type {et.GetRootType().DisplayName()}.\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["cosmos","triggers","inheritance","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"}