dotnet/efcore · error · InvalidOperationException

The IsDiscriminatorMappingComplete setting was configured to

Error message

The IsDiscriminatorMappingComplete setting was configured to '{isDiscriminatorMappingComplete1}' on '{entityType1}', but on '{entityType2}' it was configured to '{isDiscriminatorMappingComplete2}'. All entity types mapped to the same container '{container}' must be configured with the same 'IsDiscriminatorMappingComplete' value.

What it means

Thrown during Cosmos model validation when two entity types mapped to the same Cosmos container disagree on the IsDiscriminatorMappingComplete flag. The validator iterates every type in a shared container and pins the first non-null value it sees, then throws if a subsequent type carries a different value. IsDiscriminatorMappingComplete controls whether the discriminator fully identifies each row, so the container must agree.

Solutions

  1. Open the model configuration for both entity types named in the message and unify the IsDiscriminatorMappingComplete setting (pick true OR false for every type in the container).
  2. If you cannot tell which entity set the first value, search the codebase for IsComplete / IsDiscriminatorMappingComplete and remove redundant calls so the default applies uniformly.
  3. Move the configuration to a single IEntityTypeConfiguration<> for the root of the hierarchy rather than per-derived-type configs to prevent divergence.

Example fix

// before
modelBuilder.Entity<A>().ToContainer("Items").HasDiscriminator().IsComplete(true);
modelBuilder.Entity<B>().ToContainer("Items").HasDiscriminator().IsComplete(false);

// after
modelBuilder.Entity<A>().ToContainer("Items").HasDiscriminator().IsComplete(true);
modelBuilder.Entity<B>().ToContainer("Items"); // inherits the same setting from the root
Defensive patterns

Strategy: validation

Validate before calling

// Before finalizing the model, assert every type in a shared container agrees on IsDiscriminatorMappingComplete.
foreach (var container in dbContext.Model.GetEntityTypes().GroupBy(e => e.GetContainer()))
{
    bool? first = null;
    foreach (var et in container)
    {
        var v = et.GetIsDiscriminatorMappingComplete();
        if (v is null) continue;
        if (first is null) first = v;
        else if (first != v) throw new InvalidOperationException($"Mismatch on {container.Key}");
    }
}

Prevention

When it happens

Trigger: Two or more entity types share a container (TPH hierarchy or types explicitly mapped via ToContainer to the same name), and one is configured with HasDiscriminator().IsComplete(true) (or false) while another in the same container uses the opposite value or leaves it default when the first set it explicitly. Triggered at model finalization (the first time the model is built/validated, e.g. on the first query or DbContext construction).

Common situations: Splitting a TPH hierarchy where one branch was hand-configured with IsDiscriminatorMappingComplete and the rest were left at defaults; copy-paste between entities that mapped to the same container; upgrading EF Core where the default for IsDiscriminatorMappingComplete changed and partial overrides now collide.

Related errors


AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11). Data as JSON: /api/errors/09a3a6a30c210de7. Report an issue: GitHub.

Appendix: source

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

                {
                    throw new InvalidOperationException(
                        CosmosStrings.DuplicateDiscriminatorValue(
                            entityType.DisplayName(),
                            discriminatorValue,
                            duplicateEntityType.DisplayName(),
                            container));
                }

                discriminatorValues[discriminatorValue] = entityType;

                var currentIsDiscriminatorMappingComplete = entityType.GetIsDiscriminatorMappingComplete();
                if (isDiscriminatorMappingComplete == null)
                {
                    isDiscriminatorMappingComplete = currentIsDiscriminatorMappingComplete;
                }
                else if (currentIsDiscriminatorMappingComplete != isDiscriminatorMappingComplete)
                {
                    throw new InvalidOperationException(
                        CosmosStrings.IsDiscriminatorMappingCompleteMismatch(
                            isDiscriminatorMappingComplete, firstEntityType.DisplayName(), entityType.DisplayName(),
                            currentIsDiscriminatorMappingComplete, container));
                }
            }

            var currentAnalyticalTtl = entityType.GetAnalyticalStoreTimeToLive();
            if (currentAnalyticalTtl != null)
            {
                if (analyticalTtl == null)
                {
                    analyticalTtl = currentAnalyticalTtl;
                }
                else if (analyticalTtl != currentAnalyticalTtl)
                {
                    var conflictingEntityType = mappedTypes.First(et => et.GetAnalyticalStoreTimeToLive() != null);
                    throw new InvalidOperationException(
                        CosmosStrings.AnalyticalTTLMismatch(

View on GitHub (pinned to 3a2006ef56)