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
- Configure the navigation target as owned: modelBuilder.Entity<T>().OwnsOne(x => x.Navigation).
- Verify GetContainingPropertyName() on the target entity type returns a value (it is embedded).
- 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
- For Cosmos providers, configure all reference navigations you query through with OwnsOne.
- Add a model validation hook that rejects non-embedded navigations during OnModelCreating.
- Run CreateContainer/EnsureCreated early in dev to surface embedding issues.
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
- Navigation ' . ' doesn't point to an embedded entity.
- Including navigation
- A full-text index on
- A vector index on ' ' is defined over properties ` `. A…
- Property ' . ' was configured for full-text search, but has…
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)