dotnet/efcore · error · InvalidOperationException

Both properties '{property1}' and '{property2}' on entity ty

Error message

Both properties '{property1}' and '{property2}' on entity type '{entityType}' are mapped to '{storeName}'. Map one of the properties to a different JSON property.

What it means

Thrown by ValidateDatabaseProperties when two persisted properties on the same entity type map to the same JSON property name (GetJsonPropertyName). Cosmos stores entities as JSON, so two CLR properties collapsing to one JSON name would silently overwrite each other; the validator surfaces this at model validation.

Source

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

    /// <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 ValidateDatabaseProperties(
        IEntityType entityType,
        IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)
    {
        var properties = new Dictionary<string, IPropertyBase>();
        foreach (var property in entityType.GetProperties().Where(x => x.IsPersisted()))
        {
            var jsonName = property.GetJsonPropertyName();

            if (properties.TryGetValue(jsonName, out var otherProperty))
            {
                throw new InvalidOperationException(
                    CosmosStrings.JsonPropertyCollision(property.Name, otherProperty.Name, entityType.DisplayName(), jsonName));
            }

            properties[jsonName] = property;
        }

        foreach (var navigation in entityType.GetNavigations())
        {
            if (!navigation.IsEmbedded())
            {
                continue;
            }

            var jsonName = navigation.TargetEntityType.GetContainingPropertyName()!;
            if (properties.TryGetValue(jsonName, out var otherProperty))
            {
                throw new InvalidOperationException(
                    CosmosStrings.JsonPropertyCollision(navigation.Name, otherProperty.Name, entityType.DisplayName(), jsonName));

View on GitHub (pinned to dbf9771522)

Solutions

  1. Give each property a distinct ToJsonProperty value.
  2. Rename one of the conflicting CLR properties or exclude one from persistence (IsPersisted(false)/not mapped).
  3. Audit JSON names when introducing a new property to an existing entity.

Example fix

// before
modelBuilder.Entity<User>()
    .Property(u => u.Id).ToJsonProperty("name");
modelBuilder.Entity<User>()
    .Property(u => u.DisplayName).ToJsonProperty("name");

// after
modelBuilder.Entity<User>()
    .Property(u => u.Id).ToJsonProperty("id");
modelBuilder.Entity<User>()
    .Property(u => u.DisplayName).ToJsonProperty("name");
Defensive patterns

Strategy: validation

Validate before calling

using var ctx = new MyContext();
foreach (var e in ctx.Model.GetEntityTypes())
{
    var names = e.GetProperties().Where(p => p.IsPersisted()).Select(p => p.GetJsonPropertyName()).ToList();
    Debug.Assert(names.Count == names.Distinct().Count(), $"{e.Name} has colliding JSON property names");
}

Try / catch

try { ctx.Model.GetModel(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("are mapped to") && ex.Message.Contains("JSON property"))
{
    logger.LogError(ex, "Two properties collide on the same JSON name");
    throw;
}

Prevention

When it happens

Trigger: Two properties whose default or ToJsonProperty-configured names coincide, e.g. Id and id differing only by casing collapsing to the same name, or explicitly mapping two properties to the same ToJsonProperty value.

Common situations: Case-insensitive name collisions (e.g. 'Id'/'id'); renaming via ToJsonProperty to a value already used; inherited properties colliding with declared ones.

Related errors


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