dotnet/efcore · error · InvalidOperationException
Could not load assembly for IAssemblySymbol
Error message
Could not load assembly for IAssemblySymbol '{assemblySymbol.Name}' What it means
Thrown by CSharpToLinqTranslator.LoadAnonymousTypes when Assembly.Load(assemblySymbol.Name) threw FileNotFoundException and the translator has no _additionalAssembly fallback. Anonymous-type definitions must be loaded reflectively so the translator can build the closed generic anonymous Type from its members; without either path it cannot continue.
Solutions
- Pass the user's assembly (the one containing the anonymous type definition) as additionalAssembly in Load(...).
- Keep the AssemblyLoadContext that holds the user assembly alive during translation (do not unload collectible ALCs before the precompiled-query pipeline finishes).
- Avoid anonymous types in the translated query if the host cannot load the source assembly reflectively (project to a named DTO instead).
- Ensure the assembly is discoverable by Assembly.Load (correct simple name, on the default load context, or wired through AppDomain.AssemblyResolve).
Example fix
// before
translator.Load(compilation, dbContext);
// query: db.Users.Select(u => new { u.Id, u.Name })
// after
translator.Load(
compilation,
dbContext,
additionalAssembly: userQueryAssembly); Defensive patterns
Strategy: validation
Validate before calling
// Verify the user assembly (anonymous types live there) is loadable or provided.
bool CanLoadUserAssembly(Microsoft.CodeAnalysis.IAssemblySymbol asm, System.Reflection.Assembly? additional)
{
try { System.Reflection.Assembly.Load(asm.Name); return true; }
catch (System.IO.FileNotFoundException) { return additional is not null; }
} Try / catch
try
{
translator.Load(compilation, dbContext, additionalAssembly: userAssembly);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("Could not load assembly for IAssemblySymbol"))
{
throw new InvalidOperationException(
"The user's assembly could not be loaded reflectively. " +
"Pass it as additionalAssembly and keep its AssemblyLoadContext alive.", ex);
} Prevention
- Always supply additionalAssembly when hosting the translator against user code.
- Do not unload collectible AssemblyLoadContexts that hold user code until translation completes.
- Prefer named DTOs over anonymous types when hosting the translator in environments where the user assembly may not be loadable.
When it happens
Trigger: An EF query constructs an anonymous type (e.g. .Select(x => new { x.A, x.B })) and the assembly that contains the anonymous type definition is not loadable by simple name through Assembly.Load, with no additionalAssembly supplied as a fallback.
Common situations: Test harnesses where the user code lives in an assembly built and loaded into a specific AssemblyLoadContext that gets unloaded before the translator runs; source-generator host where the user assembly has not been loaded reflectively; an assembly whose simple name does not match its file identity.
Related errors
- Couldn't resolve CLR type
- Could not found symbol for parameter lambda
- Anonymous type creation without members
- Async lambdas are not supported
- Couldn't find nested type
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/d4a7be082ad8039d.
Report an issue: GitHub.
Appendix: source
Thrown at src/EFCore.Design/Query/Internal/CSharpToLinqTranslator.cs:1238
// 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)
{
Assembly? assembly;
try
{
assembly = Assembly.Load(assemblySymbol.Name);
}
catch (FileNotFoundException)
{
// If we can't find the assembly, use 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).
assembly = _additionalAssembly
?? throw new InvalidOperationException($"Could not load assembly for IAssemblySymbol '{assemblySymbol.Name}'");
}
// Get all the anonymous type in the assembly, and index them by the ordered names of their properties.
// Note that anonymous types are generic, so we don't have property types in the key.
// TODO: An alternative strategy would be to just generate the types as we need them (with ref.emit) - that's probably safer.
// TODO: Though it may mean that the resulting CLR Type can't be anonymous (Type.IsAnonymousType()) - not sure that matters.
return assembly.GetTypes()
.Where(t => t.IsAnonymousType())
.ToDictionary(t => t.GetProperties().Select(x => x.Name).ToArray(), t => t, new ArrayStructuralComparer<string>());
}
}
private sealed class ArrayStructuralComparer<T> : IEqualityComparer<T[]>
{
public bool Equals(T[]? x, T[]? y)
=> x is null ? y is null : y is not null && x.SequenceEqual(y);
View on GitHub (pinned to 3a2006ef56)