dotnet/efcore · error · NotImplementedException

Multiple labels on the same statement

Error message

Multiple labels on the same statement

What it means

Thrown in VisitBlock when a second LabeledStatementSyntax is encountered while one is already pending (pendingLabeledStatement is not null). Two labels target the same statement, which the translator does not support. NotImplementedException. Part of EF Core's LINQ-to-C# syntax translation.

Source

Thrown at src/EFCore.Design/Query/Internal/LinqToCSharpSyntaxTranslator.cs:552

            _onLastLambdaLine = parentOnLastLambdaLine && onLastBlockLine;

            // Any lines before the last are evaluated in statement context (they aren't returned); the last line is evaluated in the
            // context of the block as a whole. _context now refers to the statement's context, blockContext to the block's.
            var statementContext = onLastBlockLine ? _context : ExpressionContext.Statement;

            SyntaxNode translated;
            using (ChangeContext(statementContext))
            {
                translated = Translate(expression);
            }

            // If we have a labeled statement, unwrap it and keep the label as pending. VisitLabel returns a dummy statement (since
            // LINQ labels don't have a statement, unlike C#), so we'll skip that statement and add the label to the next real one.
            if (translated is LabeledStatementSyntax labeledStatement)
            {
                if (pendingLabeledStatement is not null)
                {
                    throw new NotImplementedException("Multiple labels on the same statement");
                }

                pendingLabeledStatement = labeledStatement;
                translated = labeledStatement.Statement;
            }

            // Syntax optimization. This is an assignment of a block variable to some value. Render this as:
            // var x = <expression>;
            // ... instead of:
            // int x;
            // x = <expression>;
            // ... except for expression context (i.e. on the last line), where we just return the value if needed.
            if (expression is BinaryExpression { NodeType: ExpressionType.Assign, Left: ParameterExpression lValue }
                && translated is AssignmentExpressionSyntax { Right: var valueSyntax }
                && statementContext == ExpressionContext.Statement
                && unassignedVariables.Remove(lValue))
            {
                var useExplicitVariableType = valueSyntax.Kind() == SyntaxKind.NullLiteralExpression;

View on GitHub (pinned to dbf9771522)

Solutions

  1. Separate the labels so each lands on its own statement (insert a no-op statement between them).
  2. Restructure the control flow to avoid co-located labels.
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: An expression block where two label targets land such that both get attached to the same statement.

Common situations: Expression trees with multiple goto labels landing on consecutive positions; uncommon control-flow patterns in generated expression trees.

Related errors


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