dotnet/efcore · error · InvalidOperationException
Identifier without symbol: {identifierName}
Error message
Identifier without symbol: {identifierName} What it means
`VisitIdentifierName` calls `GetSymbolInfo(identifierName).Symbol`; the `case null:` arm throws `InvalidOperationException` when Roslyn cannot bind the identifier to any symbol. That means the name is unresolvable in the current semantic model (undefined, or referencing something outside the compilation's references).
Source
Thrown at src/EFCore.Design/Query/Internal/CSharpToLinqTranslator.cs:422
var symbol = _semanticModel.GetSymbolInfo(identifierName).Symbol;
ITypeSymbol typeSymbol;
switch (symbol)
{
case INamedTypeSymbol s:
return Constant(ResolveType(s));
case ILocalSymbol s:
typeSymbol = s.Type;
break;
case IFieldSymbol s:
typeSymbol = s.Type;
break;
case IPropertySymbol s:
typeSymbol = s.Type;
break;
case null:
throw new InvalidOperationException($"Identifier without symbol: {identifierName}");
default:
throw new UnreachableException($"IdentifierName of type {symbol.GetType().Name}: {identifierName}");
}
// TODO: Separate out EF Core-specific logic (EF Core would extend this visitor)
if (typeSymbol.Name.Contains("DbSet"))
{
throw new NotImplementedException("DbSet local symbol");
}
// We have an identifier which isn't in our parameters stack.
// First, if the identifier type is the user's DbContext type (e.g. DbContext local variable, or field/property),
// return a constant over that.
if (typeSymbol.Equals(_userDbContextSymbol, SymbolEqualityComparer.Default))
{
return Constant(_userDbContext);
}View on GitHub (pinned to dbf9771522)
Solutions
- Add the assembly/reference that defines the identifier.
- Ensure the tree carries the right `using` directives and is in the same compilation as the `SemanticModel`.
- Replace the unresolved identifier with a resolvable equivalent.
Example fix
// before var q = ctx.Items.Where(i => Helper.Unresolved(i)); // Helper not referenced // after // add MetadataReference to Helper's assembly, then: var q = ctx.Items.Where(i => Helper.Unresolved(i));
Defensive patterns
Strategy: validation
Validate before calling
// Confirm every identifier in the query binds to a symbol before translating.
var unresolved = node.DescendantNodes().OfType<IdentifierNameSyntax>()
.FirstOrDefault(id => semanticModel.GetSymbolInfo(id).Symbol is null);
if (unresolved is not null)
throw new InvalidOperationException(
$"Identifier '{unresolved.Identifier.Text}' is unbound. Add the required references/usings.");
translator.Translate(node, semanticModel); Try / catch
try { translator.Translate(node, semanticModel); }
catch (InvalidOperationException ex) when (ex.Message.StartsWith("Identifier without symbol:"))
{ /* add missing reference/using and rebuild the SemanticModel */ } Prevention
- Make sure the tree has the right `using` directives and is in the referenced compilation.
- Reference all assemblies the query touches.
- Validate identifiers bind before translating (cheap `GetSymbolInfo` check).
When it happens
Trigger: Translating a query whose lambda references an identifier that the `SemanticModel` cannot resolve — a type/member from an unreferenced assembly, or a name that genuinely does not exist.
Common situations: Missing using-directives at the syntax-tree level, missing metadata references in the compilation, or stale `SemanticModel` from a different compilation.
Related errors
- Could not resolve type symbol for: {parameter.Type}
- ArrayCreation: non-array type symbol: {arrayCreation}
- No type for expression {elementAccessExpression.Expression}
- Could not find type symbol for: {fullyQualifiedMetadataName}
- A compilation must be loaded.
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/f092fa25cecfe9a4.
Report an issue: GitHub.