dotnet/efcore · error · InvalidOperationException

Including navigation

Error message

Including navigation '{navigation}' is not supported as the navigation is not embedded in same resource.

What it means

Thrown by CosmosProjectionBindingExpressionVisitor when it encounters a MaterializeCollectionNavigationExpression whose Navigation is not an INavigation or is not IsEmbedded(). Cosmos only supports Include on collection navigations that are configured as embedded in the same Cosmos document; non-embedded includes cannot be served from a single document read.

Solutions

  1. Configure the collection navigation as embedded: modelBuilder.Entity<Doc>().OwnsMany(d => d.RelatedItems) (or OwnsMany with ToProperty for the JSON path).
  2. If the related data genuinely lives in another container/partition, drop Include and issue separate queries, joining client-side.
  3. Confirm the navigation .IsEmbedded() returns true before using Include with it.

Example fix

// before
public class Doc { public List<Related> RelatedItems { get; set; } }
var q = ctx.Docs.Include(d => d.RelatedItems);

// after - embed the collection
modelBuilder.Entity<Doc>().OwnsMany(d => d.RelatedItems);
var q = ctx.Docs.Include(d => d.RelatedItems);   // now embedded, supported
Defensive patterns

Strategy: validation

Validate before calling

// At startup, assert any Included collection navigation is embedded.
foreach (var et in modelBuilder.Model.GetEntityTypes())
foreach (var nav in et.GetNavigations().Where(n => n.IsCollection && !n.IsEmbedded()))
    Console.Warn($"Warning: Include({et.DisplayName()}.{nav.Name}) will throw; configure as embedded or remove Include.");

Type guard

static bool CanIncludeOnCosmos(INavigation nav) => nav.IsEmbedded();

Prevention

When it happens

Trigger: Writing ctx.Docs.Include(d => d.RelatedItems) where RelatedItems is a collection navigation that is not owned/embedded (i.e. it is a separate entity set referenced by FK).

Common situations: Porting a relational Include-based graph query to Cosmos; using navigation properties that look like relations but are not configured with OwnsMany/ToProperty as embedded.

Related errors


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

Appendix: source

Thrown at src/EFCore.Cosmos/Query/Internal/CosmosProjectionBindingExpressionVisitor.cs:335

                    {
                        // This is to handle have correct type for the shaper expression. It is later fixed in MatchTypes.
                        // This mirrors for structural types what we do for scalars.
#pragma warning disable EF1001 // Internal EF Core API usage.
                        structuralTypeShaper = structuralTypeShaper.MakeClrTypeNullable();
#pragma warning restore EF1001 // Internal EF Core API usage.
                    }
                }

                structuralTypeShaper = structuralTypeShaper.Update(projectionBinding);

                return structuralTypeShaper;
            }

            case MaterializeCollectionNavigationExpression materializeCollectionNavigationExpression:
                if (materializeCollectionNavigationExpression.Navigation is not INavigation includableCollectionNavigation
                    || !includableCollectionNavigation.IsEmbedded())
                {
                    throw new InvalidOperationException(
                        CosmosStrings.NonEmbeddedIncludeNotSupported(materializeCollectionNavigationExpression.Navigation));
                }

                var subquery = materializeCollectionNavigationExpression.Subquery;
                if (subquery is MethodCallExpression { Method.IsGenericMethod: true } methodCallSubquery)
                {
                    // strip .Select(x => x) and .AsQueryable()
                    if (methodCallSubquery.Method.GetGenericMethodDefinition() == QueryableMethods.Select
                        && methodCallSubquery.Arguments[0] is MethodCallExpression selectSourceMethod)
                    {
                        methodCallSubquery = selectSourceMethod;
                    }

                    if (methodCallSubquery.Method.IsGenericMethod
                        && methodCallSubquery.Method.GetGenericMethodDefinition() == QueryableMethods.AsQueryable)
                    {
                        subquery = methodCallSubquery.Arguments[0];
                    }

View on GitHub (pinned to 3a2006ef56)