dotnet/efcore · error · InvalidOperationException

Couldn't find nested type

Error message

Couldn't find nested type '{name}' on containing type '{containingType.Name}'

What it means

Thrown by CSharpToLinqTranslator.GetClrType(INamedTypeSymbol) when the symbol has a ContainingType (i.e. it is a nested type) but Type.GetNestedType(name) on the resolved containing CLR type returned null. The name passed includes a '`arity' suffix when the nested type is generic, mirroring reflection's naming.

Solutions

  1. Avoid referencing private or non-public nested types in EF query lambdas; promote them to top-level or public if needed.
  2. Align the assembly version used by the Roslyn Compilation with the one loaded at runtime (BindingRedirect / package version match).
  3. If the nested type is generic, confirm its arity matches what reflection expects; consider closing the generic so the open-definition lookup is bypassed.
  4. If the type was renamed/moved, update references in the query or pin the package version that still contains it.

Example fix

// before — Outer.PrivateNested<T> referenced in a query, reflection can't see it
source.Where(x => x.Kind == Outer.PrivateNested<int>.KindValue);

// after — make the nested type public, or reference only its public equivalent
source.Where(x => x.Kind == Outer.PublicNested.KindValue);
Defensive patterns

Strategy: validation

Validate before calling

// Verify a nested type is reflectively discoverable before translation.
bool IsNestedTypeAccessible(Type containing, string nestedName, int arity)
{
    var name = arity > 0 ? $"{nestedName}`{arity}" : nestedName;
    return containing.GetNestedType(name,
        System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic) is not null;
}

Prevention

When it happens

Trigger: A query references a nested type that is private/inaccessible to reflection (GetNestedType only returns public nested types by default with the plain string lookup), or a nested type whose arity suffix or name does not match what reflection expects, or a version of the containing assembly where the nested type no longer exists.

Common situations: Referencing private/internal nested types in a query lambda; mismatch between the assembly version the Compilation sees and the assembly actually loaded at runtime; renamed or removed nested type after a package upgrade.

Related errors


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

Appendix: source

Thrown at src/EFCore.Design/Query/Internal/CSharpToLinqTranslator.cs:1207

            {
                return typeof(Nullable<>);
            }

            var name = symbol.ContainingType is null
                ? typeSymbol.ToDisplayString(QualifiedTypeNameSymbolDisplayFormat)
                : typeSymbol.Name;

            if (symbol.IsGenericType)
            {
                name += '`' + symbol.Arity.ToString();
            }

            if (symbol.ContainingType is not null)
            {
                var containingType = ResolveType(symbol.ContainingType);

                return containingType.GetNestedType(name)
                    ?? throw new InvalidOperationException(
                        $"Couldn't find nested type '{name}' on containing type '{containingType.Name}'");
            }

            return GetClrTypeFromAssembly(typeSymbol.ContainingAssembly, name);
        }

        Type GetClrTypeFromAssembly(IAssemblySymbol? assemblySymbol, string name)
            => (assemblySymbol is null
                    ? Type.GetType(name)!
                    : Type.GetType($"{name}, {assemblySymbol.Name}"))
                // If we can't find the Type, check the assembly where the user's DbContext type lives; this is primarily to support
                // testing, where user code is in an assembly that's built as part of the the test and loaded into a specific
                // AssemblyLoadContext (which gets unloaded later).
                ?? _additionalAssembly?.GetType(name)
                ?? throw new InvalidOperationException(
                    $"Couldn't resolve CLR type '{name}' in assembly '{assemblySymbol?.Name}'");

        Dictionary<string[], Type> LoadAnonymousTypes(IAssemblySymbol assemblySymbol)

View on GitHub (pinned to 3a2006ef56)