{"record":{"id":"e18d475462843eaf","repo":"dotnet/efcore","slug":"the-time-to-live-for-analytical-store-was-configur","errorCode":null,"errorMessage":"The time to live for analytical store was configured to '{ttl1}' on '{entityType1}', but on '{entityType2}' it was configured to '{ttl2}'. All entity types mapped to the same container '{container}' must be configured with the same time to live for analytical store.","messagePattern":"The time to live for analytical store was configured to '(.+?)' on '(.+?)', but on '(.+?)' it was configured to '(.+?)'\\. All entity types mapped to the same container '(.+?)' must be configured with the same time to live for analytical store\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelValidator.cs","lineNumber":246,"sourceCode":"                {\n                    throw new InvalidOperationException(\n                        CosmosStrings.IsDiscriminatorMappingCompleteMismatch(\n                            isDiscriminatorMappingComplete, firstEntityType.DisplayName(), entityType.DisplayName(),\n                            currentIsDiscriminatorMappingComplete, container));\n                }\n            }\n\n            var currentAnalyticalTtl = entityType.GetAnalyticalStoreTimeToLive();\n            if (currentAnalyticalTtl != null)\n            {\n                if (analyticalTtl == null)\n                {\n                    analyticalTtl = currentAnalyticalTtl;\n                }\n                else if (analyticalTtl != currentAnalyticalTtl)\n                {\n                    var conflictingEntityType = mappedTypes.First(et => et.GetAnalyticalStoreTimeToLive() != null);\n                    throw new InvalidOperationException(\n                        CosmosStrings.AnalyticalTTLMismatch(\n                            analyticalTtl,\n                            conflictingEntityType.DisplayName(),\n                            entityType.DisplayName(),\n                            currentAnalyticalTtl,\n                            container));\n                }\n            }\n\n            var currentDefaultTtl = entityType.GetDefaultTimeToLive();\n            if (currentDefaultTtl != null)\n            {\n                if (defaultTtl == null)\n                {\n                    defaultTtl = currentDefaultTtl;\n                }\n                else if (defaultTtl != currentDefaultTtl)\n                {","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelValidator.cs#L228-L264","documentation":"Thrown when the analytical-store time-to-live (AnalyticalStoreTimeToLive) differs across entity types mapped to the same Cosmos container. The Cosmos analytical store (Synapse Link) is a container-level property, so EF Core requires every type in a shared container to declare the same TTL. The validator captures the first non-null TTL and rejects any subsequent conflicting value.","triggerScenarios":"One entity type calls HasAnalyticalStoreTimeToLive(TimeSpan) while another type sharing its container calls it with a different value, or only one of them configures it after an earlier type already set it. Fires during model validation on first DbContext use.","commonSituations":"Enabling Synapse Link partway through development on only the root entity while derived/shared types retain old TTL settings; refactoring entities to share a container without unifying TTL; values supplied in different units (seconds vs TimeSpan.FromHours) producing mismatched numbers.","solutions":["Pick the TTL the whole container must use and call HasAnalyticalStoreTimeToLive with that exact value on the document-root entity only.","Remove all conflicting HasAnalyticalStoreTimeToLive calls from other types mapped to the same container.","If TTL should be null on some types, leave them unconfigured so the root value propagates."],"exampleFix":"// before\nmodelBuilder.Entity<Order>().ToContainer(\"Orders\").HasAnalyticalStoreTimeToLive(TimeSpan.FromHours(1));\nmodelBuilder.Entity<OrderHistory>().ToContainer(\"Orders\").HasAnalyticalStoreTimeToLive(TimeSpan.FromDays(1));\n\n// after\nmodelBuilder.Entity<Order>().ToContainer(\"Orders\").HasAnalyticalStoreTimeToLive(TimeSpan.FromHours(1));\n// OrderHistory inherits the container setting - do not call HasAnalyticalStoreTimeToLive again","handlingStrategy":"validation","validationCode":"var groups = dbContext.Model.GetEntityTypes()\n    .GroupBy(e => e.GetContainer());\nforeach (var g in groups)\n{\n    var ttls = g.Select(e => e.GetAnalyticalStoreTimeToLive()).Where(t => t != null).Distinct().ToList();\n    if (ttls.Count > 1) throw new InvalidOperationException($\"Container {g.Key} has conflicting analytical TTLs\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set HasAnalyticalStoreTimeToLive on one root entity only per container.","Use the same TimeSpan instance across configs to avoid silent value drift.","Add a CI test that builds the model and asserts container-wide agreement."],"tags":["cosmos","model-validation","analytical-store","ttl","configuration"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}