dotnet/efcore · error · NotImplementedException
Null argument in VisitLabelTarget
Error message
Null argument in VisitLabelTarget
What it means
VisitLabelTarget throws NotImplementedException when called with a null LabelTarget. The translator must emit a concrete C# label identifier, and with no target there is nothing to name, so it bails. The C# compiler never produces null label targets, so this indicates a malformed or hand-built tree.
Source
Thrown at src/EFCore.Design/Query/Internal/LinqToCSharpSyntaxTranslator.cs:1278
}
/// <inheritdoc />
protected override Expression VisitLabel(LabelExpression label)
{
// C# labels apply on a statement, but in LINQ they can appear anywhere (i.e. last thing in a block).
// So we apply the label to a dummy null literal statement, which we'll filter out of the block in statement context anyway.
Result = LabeledStatement(
TranslateLabelTarget(label.Target).Identifier.Text,
ExpressionStatement(LiteralExpression(SyntaxKind.NullLiteralExpression)));
return label;
}
/// <inheritdoc />
protected override LabelTarget VisitLabelTarget(LabelTarget? labelTarget)
{
if (labelTarget is null)
{
throw new NotImplementedException("Null argument in VisitLabelTarget");
}
Result = TranslateLabelTarget(labelTarget);
return labelTarget;
}
/// <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>
protected virtual IdentifierNameSyntax TranslateLabelTarget(LabelTarget labelTarget)
{
// In LINQ expression trees, label targets can have a return type (they're expressions), which means they return the last evaluated
// thing if e.g. they're the last expression in a block. This would require lifting out the last evaluation before the goto/break,
// assigning it to a temporary variable, and adding a variable evaluation after the label.
if (labelTarget.Type != typeof(void))View on GitHub (pinned to dbf9771522)
Solutions
- Always construct labels with a real target: Expression.Label(typeof(void), "name").
- Audit any programmatic expression-tree assembly for null LabelTarget references before precompiling.
- Avoid hand-built goto/label control flow inside EF Core precompiled query lambdas; restructure as conditionals or method calls.
Example fix
// before var badLabel = Expression.Label(null); // Target is null -> throws // after var label = Expression.Label(typeof(void), "done");
Defensive patterns
Strategy: validation
Validate before calling
// Verify every Label/Goto/Loop target is non-null
public sealed class NullLabelDetector : ExpressionVisitor {
public bool Found;
protected override Expression VisitLabel(LabelExpression l) { if (l.Target is null) Found = true; return l; }
protected override Expression VisitGoto(GotoExpression g) { if (g.Target is null) Found = true; return g; }
} Prevention
- Always construct labels with Expression.Label(typeof(void), "name").
- Never pass null as a LabelTarget.
- Validate hand-built control-flow trees before precompiling.
When it happens
Trigger: An expression tree contains a LabelExpression, GotoExpression, LoopExpression, or SwitchExpression whose Target/ContinueLabel/BreakLabel reference is null when visited; or VisitLabelTarget is invoked directly on null. This comes from programmatic Expression construction, e.g. Expression.Label(null) or building gotos with null targets.
Common situations: Hand-built control-flow trees passed to the precompiled-query generator; expression rewriters that replace label targets with null; integration code that assembles loops/gotos dynamically.
Related errors
- Non-void label target
- Switch with non-null comparison method
- Missing default arm for switch expression
- Empty switch statement
- DebugInfo nodes are not supporting when translating expressi
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/f199a94b99652c34.
Report an issue: GitHub.