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

  1. Always construct labels with a real target: Expression.Label(typeof(void), "name").
  2. Audit any programmatic expression-tree assembly for null LabelTarget references before precompiling.
  3. 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

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


AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06). Data as JSON: /api/errors/f199a94b99652c34. Report an issue: GitHub.