dotnet/efcore · error · NotImplementedException

Label on last expression of an expression block

Error message

Label on last expression of an expression block

What it means

Thrown in VisitBlock when a pending label remains after the last expression of an expression-context block (which gets lifted). Labels cannot be lifted out of expression blocks because there is no statement target. NotImplementedException. Part of EF Core's LINQ-to-C# syntax translation.

Source

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

            else
            {
                if (pendingLabeledStatement is not null)
                {
                    statement = pendingLabeledStatement.WithStatement(statement);
                    pendingLabeledStatement = null;
                }

                statements.Add(statement);
            }
        }

        // If a label existed on the last line of the block, add an empty statement (since C# requires it); for expression blocks we'd
        // have to lift that, not supported for now.
        if (pendingLabeledStatement is not null)
        {
            if (blockContext == ExpressionContext.Expression)
            {
                throw new NotImplementedException("Label on last expression of an expression block");
            }

            statements.Add(pendingLabeledStatement.WithStatement(EmptyStatement()));
        }

        // Above we transform top-level assignments (i = 8) to var-declarations with initializers (var i = 8); those variables have
        // already been taken care of and removed from the list.
        // But there may still be variables that get assigned inside nested blocks or other situations; prepare declarations for those
        // and either add them to the block, or lift them if we're an expression block.
        var unassignedVariableDeclarations =
            unassignedVariables.Select(v => (LocalDeclarationStatementSyntax)_g.LocalDeclarationStatement(
                Generate(v.Type), LookupVariableName(v), initializer: _g.DefaultExpression(Generate(v.Type))));

        if (blockContext == ExpressionContext.Expression)
        {
            _liftedState.UnassignedVariableDeclarations.AddRange(unassignedVariableDeclarations);
        }
        else

View on GitHub (pinned to dbf9771522)

Solutions

  1. Move the label off the last expression (add a trailing statement after the label).
  2. Translate the enclosing construct in statement context instead of expression context.
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: A block in expression context whose final expression is a label - the label would need lifting but expression context has no statement target.

Common situations: Expression trees with labels positioned at the tail of a lifted block; rare control-flow shapes.

Related errors


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