dotnet/efcore · error · InvalidOperationException

Navigation ' . ' doesn't point to an embedded entity.

Error message

Navigation '{entityType}.{navigationName}' doesn't point to an embedded entity.

What it means

ObjectAccessExpression's constructor throws when an INavigation is being bound as a single-object access but the navigation's target entity type has no containing property name (GetContainingPropertyName() returns null). In Cosmos, single-object navigations must point to embedded (owned) entities; a navigation whose target is not owned has no JSON path to bind against.

Solutions

  1. Configure the navigation target as owned: modelBuilder.Entity<T>().OwnsOne(x => x.Navigation).
  2. Verify GetContainingPropertyName() on the target entity type returns a value (it is embedded).
  3. Avoid querying through that navigation if it should remain a separate document relationship.

Example fix

// before
modelBuilder.Entity<Order>().HasOne(o => o.Customer).WithMany();

// after - customer is embedded inside the order document
modelBuilder.Entity<Order>().OwnsOne(o => o.Customer);
Defensive patterns

Strategy: validation

Validate before calling

// Validate at model build time that reference navigations used in Cosmos queries are owned.
foreach (var nav in entityType.GetNavigations().Where(n => !n.IsCollection && n.TargetEntityType.GetContainingPropertyName() == null))
{
    throw new InvalidOperationException($"Navigation {entityType.DisplayName()}.{nav.Name} is not embedded; configure OwnsOne.");
}

Type guard

static bool IsEmbeddedNavigation(INavigation n) => n.TargetEntityType.GetContainingPropertyName() is not null;

Prevention

When it happens

Trigger: Querying through a reference navigation whose target type was not configured as owned (ToOwnership/OwnsOne) in OnModelCreating.

Common situations: Defining a HasOne/WithMany relationship between two entities without making the target owned, then including or projecting that navigation in a Cosmos query.

Related errors


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

Appendix: source

Thrown at src/EFCore.Cosmos/Query/Internal/Expressions/ObjectAccessExpression.cs:38

    /// <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>
    public ObjectAccessExpression(
        Expression @object,
        IPropertyBase structuralProperty)
    {
        ITypeBase structuralType;
        string propertyName;

        switch (structuralProperty)
        {
            case INavigation navigation:
                structuralType = navigation.TargetEntityType;
                propertyName = navigation.TargetEntityType.GetContainingPropertyName()
                    ?? throw new InvalidOperationException(
                        CosmosStrings.NavigationPropertyIsNotAnEmbeddedEntity(
                            navigation.DeclaringEntityType.DisplayName(), navigation.Name));
                break;
            case IComplexProperty complexProperty:
                structuralType = complexProperty.ComplexType;
                propertyName = complexProperty.GetJsonPropertyName();
                break;
            default:
                throw new UnreachableException($"Unexpected structural property type: {structuralProperty.GetType().FullName}");
        }

        PropertyName = propertyName;
        StructuralProperty = structuralProperty;
        Object = @object;
        StructuralType = structuralType;
    }

    /// <summary>

View on GitHub (pinned to 3a2006ef56)